From 187b5ab6326fcfa0281af640080f071ac1ccca43 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:14:03 -0500 Subject: [PATCH 01/48] add helix sdk --- global.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/global.json b/global.json index 0530bb2185..1aef5fd93c 100644 --- a/global.json +++ b/global.json @@ -18,6 +18,7 @@ "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.5.0", "Microsoft.Build.Traversal": "3.4.0", - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26080.4" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26080.4", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.26080.4" } } From d6bb8df6dd83b8407e96e8e03d6b4a5e8b55d6c6 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:14:39 -0500 Subject: [PATCH 02/48] refactor cdb/testassets to be copied to artifacts dir --- .../DbgShim.UnitTests.csproj | 24 +++----- src/tests/Directory.Build.props | 9 +++ src/tests/Directory.Build.targets | 58 ++++++++++++++++++- src/tests/SOS.UnitTests/SOS.UnitTests.csproj | 7 +-- 4 files changed, 76 insertions(+), 22 deletions(-) diff --git a/src/tests/DbgShim.UnitTests/DbgShim.UnitTests.csproj b/src/tests/DbgShim.UnitTests/DbgShim.UnitTests.csproj index c931e79852..f17b7599e9 100644 --- a/src/tests/DbgShim.UnitTests/DbgShim.UnitTests.csproj +++ b/src/tests/DbgShim.UnitTests/DbgShim.UnitTests.csproj @@ -6,6 +6,8 @@ $(OutputPath)$(TargetFramework)\Debugger.Tests.Common.txt 1.0.351101 true + true + true @@ -28,16 +30,6 @@ - - - - - - - - - - @@ -48,10 +40,10 @@ $(Configuration) $(ArtifactsDir) - $(NuGetPackageRoot)testassets.windows.x64.6.0\$(TestAssetsVersion)\content - $(NuGetPackageRoot)testassets.windows.x86.6.0\$(TestAssetsVersion)\content - $(NuGetPackageRoot)testassets.linux.x64.6.0\$(TestAssetsVersion)\content - $(NuGetPackageRoot)testassets.linux.arm64.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\testassets.windows.x64.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\testassets.windows.x86.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\testassets.linux.x64.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\testassets.linux.arm64.6.0\$(TestAssetsVersion)\content ]]> @@ -68,8 +60,8 @@ $(Configuration) $(ArtifactsDir) - $(NuGetPackageRoot)testassets.linux.x64.6.0/$(TestAssetsVersion)/content - $(NuGetPackageRoot)testassets.linux.arm64.6.0/$(TestAssetsVersion)/content + %24(ArtifactsDir)test/packages/testassets.linux.x64.6.0/$(TestAssetsVersion)/content + %24(ArtifactsDir)test/packages/testassets.linux.arm64.6.0/$(TestAssetsVersion)/content ]]> diff --git a/src/tests/Directory.Build.props b/src/tests/Directory.Build.props index e36d68d633..9f63e06a15 100644 --- a/src/tests/Directory.Build.props +++ b/src/tests/Directory.Build.props @@ -1,3 +1,12 @@ + + + $([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'test', 'packages')) + + + + true + true + diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index ab42c9ad55..373bd53110 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -6,7 +6,8 @@ Projects opt-in by setting CopyDebuggeeSourcesToArtifacts=true. Optional: Set CopyLldbPluginTests=true to also copy lldbplugin.tests. --> - + $(ArtifactsDir)test/DebuggeeSources/$(MSBuildProjectName)/Debuggees $(ArtifactsDir)test/AuxMsbuildFiles @@ -32,4 +33,59 @@ + + + + + + + + + + + + + + + + + + <_cdbFiles Include="$(NuGetPackageRoot)cdb-sos\$(cdbsosversion)\**\*" + Condition="'$(NeedsCdb)' == 'true'" /> + + <_testAssetsWinx64 Include="$(NuGetPackageRoot)testassets.windows.x64.6.0\$(TestAssetsVersion)\**\*" + Condition="'$(NeedsTestAssets)' == 'true' and '$(OS)' == 'Windows_NT'" /> + + <_testAssetsWinx86 Include="$(NuGetPackageRoot)testassets.windows.x86.6.0\$(TestAssetsVersion)\**\*" + Condition="'$(NeedsTestAssets)' == 'true' and '$(OS)' == 'Windows_NT'" /> + + <_testAssetsLinux64 Include="$(NuGetPackageRoot)testassets.linux.x64.6.0\$(TestAssetsVersion)\**\*" + Condition="'$(NeedsTestAssets)' == 'true'" /> + + <_testAssetsLinuxArm64 Include="$(NuGetPackageRoot)testassets.linux.arm64.6.0\$(TestAssetsVersion)\**\*" + Condition="'$(NeedsTestAssets)' == 'true'" /> + + + + + + + + + + + + diff --git a/src/tests/SOS.UnitTests/SOS.UnitTests.csproj b/src/tests/SOS.UnitTests/SOS.UnitTests.csproj index f4a9e017d0..ef2ff4364a 100644 --- a/src/tests/SOS.UnitTests/SOS.UnitTests.csproj +++ b/src/tests/SOS.UnitTests/SOS.UnitTests.csproj @@ -8,6 +8,7 @@ $(OutputPath)$(TargetFramework)\Debugger.Tests.Common.txt true true + true @@ -36,10 +37,6 @@ - - - - @@ -49,7 +46,7 @@ $(DesktopTargetFramework) $(NetCoreAppMinTargetFramework) $(ArtifactsDir) - $(NuGetPackageRoot)cdb-sos\$(cdbsosversion)\runtimes\win-%24(TargetArchitecture)\native\cdb.exe + %24(ArtifactsDir)test\packages\cdb-sos\$(cdbsosversion)\runtimes\win-%24(TargetArchitecture)\native\cdb.exe ]]> From 4753f3c391b9cbb6c47662601a2348a52cc2da38 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 11 Feb 2026 16:24:18 -0500 Subject: [PATCH 03/48] update DebugServices.UnitTests to get rid of $(RepoRoot) --- .../Unix/Debugger.Tests.Config.txt | 3 +- .../Windows/Debugger.Tests.Config.txt | 3 +- ...Diagnostics.DebugServices.UnitTests.csproj | 31 +++++++------------ 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt b/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt index e72e581b9e..400f9cf56d 100644 --- a/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt +++ b/src/tests/Microsoft.Diagnostics.DebugServices.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt @@ -1,8 +1,7 @@ - $(RepoRootDir)/artifacts - $(RootBinDir)/bin/$(OS).$(TargetArchitecture).$(TargetConfiguration) + $(ArtifactsDir)bin/$(OS).$(TargetArchitecture).$(TargetConfiguration) @@ -19,17 +21,6 @@ - - - - - - - - - - - Debugger.Tests.Config.txt @@ -50,13 +41,13 @@ $(Configuration) - $(RepoRoot) + $(ArtifactsDir) $(RunTests) - $(NuGetPackageRoot)cdb-sos\$(cdbsosversion)\runtimes\win-%24(TargetArchitecture)\native\dbgeng.dll - $(NuGetPackageRoot)testassets.windows.x64.6.0\$(TestAssetsVersion)\content - $(NuGetPackageRoot)testassets.windows.x86.6.0\$(TestAssetsVersion)\content - $(NuGetPackageRoot)testassets.linux.x64.6.0\$(TestAssetsVersion)\content - $(NuGetPackageRoot)testassets.linux.arm64.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\cdb-sos\$(cdbsosversion)\runtimes\win-%24(TargetArchitecture)\native\dbgeng.dll + %24(ArtifactsDir)test\packages\testassets.windows.x64.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\testassets.windows.x86.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\testassets.linux.x64.6.0\$(TestAssetsVersion)\content + %24(ArtifactsDir)test\packages\testassets.linux.arm64.6.0\$(TestAssetsVersion)\content ]]> @@ -72,10 +63,10 @@ $(Configuration) - $(RepoRoot) + $(ArtifactsDir) $(RunTests) - $(NuGetPackageRoot)testassets.linux.x64.6.0/$(TestAssetsVersion)/content - $(NuGetPackageRoot)testassets.linux.arm64.6.0/$(TestAssetsVersion)/content + %24(ArtifactsDir)test/packages/testassets.linux.x64.6.0/$(TestAssetsVersion)/content + %24(ArtifactsDir)test/packages/testassets.linux.arm64.6.0/$(TestAssetsVersion)/content ]]> From 40c1ddba41d4174ef2ae9d93351313409db51b83 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 11 Feb 2026 18:20:45 -0500 Subject: [PATCH 04/48] update AuxMsbuildFiles to not use Arcade --- eng/AuxMsbuildFiles/Directory.Build.props | 5 +---- eng/AuxMsbuildFiles/Directory.Build.targets | 2 -- src/tests/Directory.Build.targets | 21 ++++++++++++++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/eng/AuxMsbuildFiles/Directory.Build.props b/eng/AuxMsbuildFiles/Directory.Build.props index 8231a8a4fd..22b6efee36 100644 --- a/eng/AuxMsbuildFiles/Directory.Build.props +++ b/eng/AuxMsbuildFiles/Directory.Build.props @@ -1,8 +1,5 @@ - - - + bin\ diff --git a/eng/AuxMsbuildFiles/Directory.Build.targets b/eng/AuxMsbuildFiles/Directory.Build.targets index 6384491004..8bf348bb69 100644 --- a/eng/AuxMsbuildFiles/Directory.Build.targets +++ b/eng/AuxMsbuildFiles/Directory.Build.targets @@ -1,6 +1,4 @@ - - diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index 373bd53110..9061e8ca91 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -7,7 +7,8 @@ Optional: Set CopyLldbPluginTests=true to also copy lldbplugin.tests. --> + Condition="'$(CopyDebuggeeSourcesToArtifacts)' == 'true' or '$(NeedsCdb)' == 'true'" + DependsOnTargets="CopyVersionsProps"> $(ArtifactsDir)test/DebuggeeSources/$(MSBuildProjectName)/Debuggees $(ArtifactsDir)test/AuxMsbuildFiles @@ -33,6 +34,24 @@ + + + + <_AuxDir>$(ArtifactsDir)test/AuxMsbuildFiles/ + + + + + + Date: Wed, 11 Feb 2026 18:21:52 -0500 Subject: [PATCH 05/48] add helix support --- diagnostics.yml | 55 ++++ eng/helix.proj | 245 ++++++++++++++++++ eng/pipelines/global-variables.yml | 35 +++ eng/pipelines/helix.yml | 183 +++++++++++++ eng/send-to-helix.cmd | 170 ++++++++++++ eng/send-to-helix.sh | 217 ++++++++++++++++ .../TestConfiguration.cs | 37 +++ 7 files changed, 942 insertions(+) create mode 100644 eng/helix.proj create mode 100644 eng/pipelines/helix.yml create mode 100644 eng/send-to-helix.cmd create mode 100644 eng/send-to-helix.sh diff --git a/diagnostics.yml b/diagnostics.yml index 389526e741..fa9efc693b 100644 --- a/diagnostics.yml +++ b/diagnostics.yml @@ -19,6 +19,10 @@ parameters: displayName: Build only (skip tests) type: boolean default: false +- name: useHelix + displayName: Run tests on Helix (distributed testing) + type: boolean + default: false trigger: none @@ -282,9 +286,60 @@ extends: - configuration: Debug architecture: x64 + ############################ + # # + # Helix Test Stage # + # # + ############################ + + - ${{ if and(eq(parameters.useHelix, true), ne(parameters.buildOnly, true)) }}: + - stage: helix + displayName: Run Tests on Helix + dependsOn: build + jobs: + # Windows x64 Helix tests + - template: /eng/pipelines/helix.yml + parameters: + name: Helix_Windows + jobTemplate: ${{ variables.jobTemplate }} + osGroup: Windows_NT + configuration: Release + architecture: x64 + helixQueues: $(HelixQueuesWindows_x64) + isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} + dependsOn: Windows_x64_Release + + # Linux x64 Helix tests + - template: /eng/pipelines/helix.yml + parameters: + name: Helix_Linux + jobTemplate: ${{ variables.jobTemplate }} + osGroup: Linux + configuration: Release + architecture: x64 + helixQueues: $(HelixQueuesLinux_x64) + isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} + dependsOn: Linux_x64_Release + + # MacOS x64 Helix tests + - template: /eng/pipelines/helix.yml + parameters: + name: Helix_MacOS + jobTemplate: ${{ variables.jobTemplate }} + osGroup: MacOS + configuration: Release + architecture: x64 + helixQueues: $(HelixQueuesMacOS_x64) + isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} + dependsOn: MacOS_x64_Release + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - stage: package displayName: Package, Sign, and Generate BAR Manifests + ${{ if eq(parameters.useHelix, true) }}: + dependsOn: helix + ${{ else }}: + dependsOn: build jobs: - template: /eng/common/templates-official/job/job.yml parameters: diff --git a/eng/helix.proj b/eng/helix.proj new file mode 100644 index 0000000000..452633dc7d --- /dev/null +++ b/eng/helix.proj @@ -0,0 +1,245 @@ + + + + + + + msbuild + net8.0 + + + pr/$(BUILD_REPOSITORY_NAME)/$(BUILD_SOURCEBRANCH) + local/diagnostics + test/$(Configuration)/$(TargetArchitecture)/ + $(BUILD_BUILDNUMBER) + 0.0.0.0 + + + $(ArtifactsDir) + 00:30:00 + + + true + true + + + true + sdk + 10.0.102 + + + <_CorrelationPayload Condition="'$(TargetOS)' == 'Windows_NT'">%HELIX_CORRELATION_PAYLOAD% + <_CorrelationPayload Condition="'$(TargetOS)' != 'Windows_NT'">$HELIX_CORRELATION_PAYLOAD + <_UploadRoot Condition="'$(TargetOS)' == 'Windows_NT'">%HELIX_WORKITEM_UPLOAD_ROOT% + <_UploadRoot Condition="'$(TargetOS)' != 'Windows_NT'">$HELIX_WORKITEM_UPLOAD_ROOT + <_PathSep Condition="'$(TargetOS)' == 'Windows_NT'">\ + <_PathSep Condition="'$(TargetOS)' != 'Windows_NT'">/ + <_DotNetCliDir>$(_CorrelationPayload)$(_PathSep)dotnet-cli + <_ArtifactsDir>$(_CorrelationPayload)$(_PathSep)artifacts$(_PathSep) + <_VersionsFile>$(_ArtifactsDir)dotnet-test$(_PathSep)Debugger.Tests.Versions.txt + + + set "DIAGNOSTICS_ARTIFACTS_DIR=$(_ArtifactsDir)" && set "RunningOnHelix=true" && copy /Y "$(_VersionsFile)" "$(_DotNetCliDir)$(_PathSep)Debugger.Tests.Versions.txt" + export DIAGNOSTICS_ARTIFACTS_DIR="$(_ArtifactsDir)" && export RunningOnHelix=true && cp -f "$(_VersionsFile)" "$(_DotNetCliDir)/Debugger.Tests.Versions.txt" + + + <_VersionsStagingDir>$(ArtifactsDir)tmp\helix\dotnet-test\ + + <_BuildConfigStagingDir>$(ArtifactsDir)tmp\helix\build-config\ + + + + + + + runtime + + + aspnetcore-runtime + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + artifacts/bin/dotnet-trace + + + artifacts/bin/dotnet-dump + + + artifacts/bin/dotnet-counters + + + + + + + artifacts/test + + + + + + + artifacts/bin/$(TargetOS).$(TargetArchitecture).$(Configuration) + + + + + + + artifacts/bin/SOS.UnitTests + + + + + + <_DebuggeeName Include="Tracee;EventPipeTracee;ExitCodeTracee;StackTracee" /> + <_DebuggeeName Include="SimpleDebuggee;AsyncMain;DivZero;DumpGCData;WebApp3;LineNums;Overflow;SimpleThrow" /> + <_DebuggeeName Include="NestedExceptionTest;TaskNestedException;ReflectionTest;GCPOH;GCWhere" /> + <_DebuggeeName Include="MiniDumpLocalVarLookup;VarargPInvokeInteropMD;DynamicMethod;DotnetDumpCommands" /> + <_DebuggeeName Include="FindRootsOlderGeneration;SymbolTestApp;SymbolTestDll;RandomUserLibrary;TestExtension" /> + + + + + + artifacts/bin/%(Identity) + + + + + + + + + + + <_VersionsLines Include="<Configuration>" /> + <_VersionsLines Include="@(RuntimeTestVersions->' <RuntimeVersion%(Identity)>%(Runtime)</RuntimeVersion%(Identity)>')" /> + <_VersionsLines Include="@(RuntimeTestVersions->' <AspNetCoreVersion%(Identity)>%(AspNet)</AspNetCoreVersion%(Identity)>')" /> + <_VersionsLines Include="@(RuntimeTestVersions->' <TargetFramework%(Identity)>%(TargetFramework)</TargetFramework%(Identity)>')" /> + <_VersionsLines Include="</Configuration>" /> + + + + + + + + + + artifacts/dotnet-test + + + + + + + + + + + + + + + + + + artifacts + + + + + + + + + + + + $(TestArtifactsDir)bin\%(HelixPureTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) + dotnet test %(HelixPureTestProject.Identity).dll --logger "trx;LogFileName=%(HelixPureTestProject.Identity).trx" --results-directory $(_UploadRoot) + $(TestTimeout) + + + + + + + $(TestArtifactsDir)bin\%(HelixComplexTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) + dotnet test %(HelixComplexTestProject.Identity).dll --logger "trx;LogFileName=%(HelixComplexTestProject.Identity).trx" --results-directory $(_UploadRoot) + $(TestTimeout) + + + + + + + $(TestArtifactsDir)bin\%(HelixNativeTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) + dotnet test %(HelixNativeTestProject.Identity).dll --logger "trx;LogFileName=%(HelixNativeTestProject.Identity).trx" --results-directory $(_UploadRoot) + $(TestTimeout) + + + + + + + diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index 92a3439d9f..3b5cadd6ef 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -57,3 +57,38 @@ variables: - ${{ if eq(parameters.runtimeFeedToken, 'dotnetclimsrc-sas-token-base64') }}: - name: RuntimeFeedBase64SasToken value: $(dotnetclimsrc-read-sas-token-base64) + +# Helix queue configuration +# Public (open) queues for PR validation +- ${{ if eq(variables['System.TeamProject'], 'public') }}: + - name: HelixQueuesWindows_x64 + value: Windows.10.Amd64.Open + - name: HelixQueuesWindows_x86 + value: Windows.10.Amd64.Open + - name: HelixQueuesLinux_x64 + value: Ubuntu.2204.Amd64.Open + - name: HelixQueuesLinux_arm64 + value: Ubuntu.2204.Arm64.Open + - name: HelixQueuesMacOS_x64 + value: OSX.1200.Amd64.Open + - name: HelixQueuesMacOS_arm64 + value: OSX.1200.Arm64.Open + - name: HelixQueuesFreeBSD + value: '' + +# Internal queues for official builds +- ${{ if ne(variables['System.TeamProject'], 'public') }}: + - name: HelixQueuesWindows_x64 + value: Windows.10.Amd64 + - name: HelixQueuesWindows_x86 + value: Windows.10.Amd64 + - name: HelixQueuesLinux_x64 + value: Ubuntu.2204.Amd64 + - name: HelixQueuesLinux_arm64 + value: Ubuntu.2204.Arm64 + - name: HelixQueuesMacOS_x64 + value: OSX.1200.Amd64 + - name: HelixQueuesMacOS_arm64 + value: OSX.1200.Arm64 + - name: HelixQueuesFreeBSD + value: '' diff --git a/eng/pipelines/helix.yml b/eng/pipelines/helix.yml new file mode 100644 index 0000000000..53d9045f16 --- /dev/null +++ b/eng/pipelines/helix.yml @@ -0,0 +1,183 @@ +# Pipeline template for running tests on Helix +# This template sends test workloads to Helix machines for distributed execution + +parameters: + # Job name suffix +- name: name + type: string + default: 'Helix' + +- name: jobTemplate + type: string + default: /eng/common/templates/job/job.yml@self + values: + - /eng/common/templates-official/job/job.yml@self + - /eng/common/templates/job/job.yml@self + +- name: osGroup + type: string + default: Windows_NT + values: + - Windows_NT + - Linux + - MacOS + + # Build configuration +- name: configuration + type: string + default: Debug + + # Target architecture +- name: architecture + type: string + default: x64 + + # Helix queue to target (semicolon-delimited list supported) +- name: helixQueues + type: string + default: '' + + # Whether this is an internal (authenticated) build +- name: isInternal + type: boolean + default: false + + # Job timeout +- name: timeoutInMinutes + type: number + default: 120 + + # Job dependencies (build job name without architecture/configuration suffix) +- name: dependsOn + type: string + default: '' + + # Template context for 1ES pipeline +- name: templateContext + type: object + default: {} + +jobs: +- template: ${{ parameters.jobTemplate }} + parameters: + name: ${{ parameters.name }}_${{ parameters.architecture }}_${{ parameters.configuration }} + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + templateContext: ${{ parameters.templateContext }} + + # Note: cross-stage job dependencies are not supported in Azure Pipelines. + # The stage-level dependsOn handles this. We keep dependsOn parameter for + # artifact naming only. + + pool: + ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + name: $(BuildPool) + demands: ImageOverride -equals $(WindowsImage) + os: windows + + ${{ if eq(parameters.osGroup, 'Linux') }}: + name: $(BuildPool) + demands: ImageOverride -equals $(LinuxImage) + os: linux + + ${{ if eq(parameters.osGroup, 'MacOS') }}: + name: Azure Pipelines + vmImage: $(macOSImage) + os: macOS + + workspace: + clean: all + + variables: + - _BuildConfig: ${{ parameters.configuration }} + - _HelixType: test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + + # Determine target OS for helix.proj + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - _TargetOS: Windows_NT + - ${{ if eq(parameters.osGroup, 'Linux') }}: + - _TargetOS: linux + - ${{ if eq(parameters.osGroup, 'MacOS') }}: + - _TargetOS: osx + + # Helix queue configuration + - _HelixQueues: ${{ parameters.helixQueues }} + + # For internal builds, use the Helix access token + - ${{ if eq(parameters.isInternal, true) }}: + - group: DotNet-HelixApi-Access + - _HelixAccessToken: $(HelixApiAccessToken) + - _HelixSource: official/diagnostics/$(Build.SourceBranch) + - ${{ else }}: + - _HelixAccessToken: '' + - _HelixSource: pr/diagnostics/$(Build.SourceBranch) + - _Creator: $(Build.RequestedFor) + + steps: + # Download build artifacts from the build job + - task: DownloadPipelineArtifact@2 + displayName: 'Download Build Artifacts' + inputs: + targetPath: '$(Build.SourcesDirectory)/artifacts' + artifactName: Build_${{ parameters.dependsOn }} + checkDownloadedFiles: true + + # Send tests to Helix + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - script: > + $(Build.SourcesDirectory)\eng\common\msbuild.cmd + $(Build.SourcesDirectory)\eng\helix.proj + /restore + /t:Test + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=$(_TargetOS) + /p:HelixTargetQueues=$(_HelixQueues) + /p:HelixSource=$(_HelixSource) + /p:HelixType=$(_HelixType) + /p:HelixAccessToken=$(_HelixAccessToken) + ${{ if eq(parameters.isInternal, false) }}:/p:Creator=$(_Creator) + /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /t:Test + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=$(_TargetOS) + /p:HelixTargetQueues=$(_HelixQueues) + /p:HelixSource=$(_HelixSource) + /p:HelixType=$(_HelixType) + /p:HelixAccessToken=$(_HelixAccessToken) + ${{ if eq(parameters.isInternal, false) }}:/p:Creator=$(_Creator) + /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + # Publish Helix logs + - task: CopyFiles@2 + displayName: Gather Helix Logs + inputs: + sourceFolder: '$(Build.SourcesDirectory)/artifacts' + contents: 'log/**' + targetFolder: '$(Build.StagingDirectory)/HelixLogs' + continueOnError: true + condition: always() + + - template: /eng/pipelines/publish-pipeline-artifact-shim.yml@self + parameters: + displayName: Publish Helix Logs + inputs: + targetPath: '$(Build.StagingDirectory)/HelixLogs' + artifactName: HelixLogs_${{ parameters.name }}_${{ parameters.osGroup }}_${{ parameters.architecture }}_${{ parameters.configuration }} + sbomEnabled: false + continueOnError: true + condition: always() diff --git a/eng/send-to-helix.cmd b/eng/send-to-helix.cmd new file mode 100644 index 0000000000..cce321a0bd --- /dev/null +++ b/eng/send-to-helix.cmd @@ -0,0 +1,170 @@ +@echo off +REM Licensed to the .NET Foundation under one or more agreements. +REM The .NET Foundation licenses this file to you under the MIT license. + +REM Send diagnostics tests to Helix for remote execution. +REM +REM Usage: send-to-helix.cmd [options] +REM +REM Options: +REM -configuration Build configuration (default: Debug) +REM -architecture Target architecture (default: x64) +REM -queue Helix queue to target (default: Windows.10.Amd64.Open) +REM -accesstoken Helix access token for internal queues (optional) +REM -creator Creator name for public builds (optional) +REM -bl Generate binary log +REM -help Show this help message + +setlocal enabledelayedexpansion + +set "EngRoot=%~dp0" +set "EngRoot=%EngRoot:~0,-1%" +for %%i in ("%EngRoot%\..") do set "RepoRoot=%%~fi" +set "Configuration=Debug" +set "Architecture=x64" +set "TargetOS=Windows_NT" +set "HelixQueue=Windows.10.Amd64" +set "HelixAccessToken=AAAE1Eq55IR3-s8xjJvkFcHtmI0" +set "Creator=" +set "BinaryLog=" + +REM Parse arguments +:parse_args +if "%~1"=="" goto :done_parsing +if /i "%~1"=="-configuration" ( + set "Configuration=%~2" + shift + shift + goto :parse_args +) +if /i "%~1"=="-c" ( + set "Configuration=%~2" + shift + shift + goto :parse_args +) +if /i "%~1"=="-architecture" ( + set "Architecture=%~2" + shift + shift + goto :parse_args +) +if /i "%~1"=="-a" ( + set "Architecture=%~2" + shift + shift + goto :parse_args +) +if /i "%~1"=="-queue" ( + set "HelixQueue=%~2" + shift + shift + goto :parse_args +) +if /i "%~1"=="-accesstoken" ( + set "HelixAccessToken=%~2" + shift + shift + goto :parse_args +) +if /i "%~1"=="-creator" ( + set "Creator=%~2" + shift + shift + goto :parse_args +) +if /i "%~1"=="-bl" ( + if not exist "%RepoRoot%\artifacts\helix-log" mkdir "%RepoRoot%\artifacts\helix-log" + set "BinaryLog=/bl:%RepoRoot%\artifacts\helix-log\SendToHelix.binlog" + shift + goto :parse_args +) +if /i "%~1"=="-help" goto :show_help +if /i "%~1"=="-h" goto :show_help +if /i "%~1"=="/?" goto :show_help + +echo Unknown argument: %~1 +goto :show_help + +:done_parsing + +REM Set required environment variables for local Helix execution +if "%BUILD_SOURCEBRANCH%"=="" set "BUILD_SOURCEBRANCH=local" +if "%BUILD_REPOSITORY_NAME%"=="" set "BUILD_REPOSITORY_NAME=diagnostics" +if "%SYSTEM_TEAMPROJECT%"=="" set "SYSTEM_TEAMPROJECT=dnceng" +if "%BUILD_REASON%"=="" set "BUILD_REASON=Manual" + +REM Build creator argument if specified +set "CreatorArg=" +if not "%Creator%"=="" set "CreatorArg=/p:Creator=%Creator%" + +REM Build access token argument if specified +set "AccessTokenArg=" +if not "%HelixAccessToken%"=="" set "AccessTokenArg=/p:HelixAccessToken=%HelixAccessToken%" + +echo. +echo =========================== +echo Sending tests to Helix +echo =========================== +echo Configuration: %Configuration% +echo Architecture: %Architecture% +echo Target OS: %TargetOS% +echo Helix Queue: %HelixQueue% +echo Artifacts Dir: %RepoRoot%\artifacts\ +echo. + +REM Verify artifacts exist +if not exist "%RepoRoot%\artifacts\bin" ( + echo ERROR: Build artifacts not found at %RepoRoot%\artifacts\bin + echo Please run Build.cmd first to build the tests. + exit /b 1 +) + +REM Send to Helix using PowerShell (use /tl:off to disable terminal logger for better output) +REM The PrepareCorrelationPayload target runs automatically before Test +REM Set environment variables in PowerShell scope for the Helix SDK to read +powershell -ExecutionPolicy ByPass -NoProfile -command "$env:BUILD_SOURCEBRANCH='%BUILD_SOURCEBRANCH%'; $env:BUILD_REPOSITORY_NAME='%BUILD_REPOSITORY_NAME%'; $env:SYSTEM_TEAMPROJECT='%SYSTEM_TEAMPROJECT%'; $env:BUILD_REASON='%BUILD_REASON%'; & '%RepoRoot%\eng\common\msbuild.ps1' '%RepoRoot%\eng\helix.proj' /restore /t:Test /tl:off /p:Configuration=%Configuration% /p:TargetArchitecture=%Architecture% /p:TargetOS=%TargetOS% /p:HelixTargetQueues=%HelixQueue% /p:TestArtifactsDir='%RepoRoot%\artifacts\' /p:EnableAzurePipelinesReporter=false %AccessTokenArg% %CreatorArg% %BinaryLog%" + +if %ERRORLEVEL% neq 0 ( + echo. + echo ERROR: Failed to send tests to Helix + exit /b %ERRORLEVEL% +) + +echo. +echo Tests submitted to Helix successfully! +echo View results at: https://helix.dot.net/ +exit /b 0 + +:show_help +echo. +echo Send diagnostics tests to Helix for remote execution. +echo. +echo Usage: send-to-helix.cmd [options] +echo. +echo Options: +echo -configuration ^ Build configuration (default: Debug) +echo -architecture ^ Target architecture (default: x64) +echo -queue ^ Helix queue to target (default: Windows.10.Amd64.Open) +echo -accesstoken ^ Helix access token for internal queues +echo -creator ^ Creator name for public builds +echo -bl Generate binary log +echo -help Show this help message +echo. +echo Examples: +echo send-to-helix.cmd +echo send-to-helix.cmd -configuration Release -queue Windows.11.Amd64.Open +echo send-to-helix.cmd -architecture arm64 -queue Windows.11.Arm64.Open +echo send-to-helix.cmd -creator "MyName" -bl +echo. +echo Notes: +echo - Run Build.cmd first to build the test artifacts +echo - For internal queues (not ending in .Open), provide -accesstoken +echo - Public queues require -creator to be set +echo. +echo Available public Windows queues: +echo Windows.10.Amd64.Open +echo Windows.11.Amd64.Open +echo Windows.11.Arm64.Open +echo. +exit /b 0 diff --git a/eng/send-to-helix.sh b/eng/send-to-helix.sh new file mode 100644 index 0000000000..e4e3232625 --- /dev/null +++ b/eng/send-to-helix.sh @@ -0,0 +1,217 @@ +#!/usr/bin/env bash +# Licensed to the .NET Foundation under one or more agreements. +# The .NET Foundation licenses this file to you under the MIT license. + +# Send diagnostics tests to Helix for remote execution. +# +# Usage: send-to-helix.sh [options] +# +# Options: +# -configuration Build configuration (default: Debug) +# -architecture Target architecture (default: x64) +# -os Target OS (default: auto-detected) +# -queue Helix queue to target (default: auto-selected based on OS) +# -accesstoken Helix access token for internal queues (optional) +# -creator Creator name for public builds (optional) +# -bl Generate binary log +# -help Show this help message + +set -e + +# Get script directory +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_root="$(cd "$script_dir/.." && pwd)" + +# Default values +configuration="Debug" +architecture="x64" +target_os="" +helix_queue="" +helix_access_token="" +creator="" +binary_log="" + +# Detect OS +detect_os() { + case "$(uname -s)" in + Linux*) echo "linux" ;; + Darwin*) echo "osx" ;; + *) echo "unknown" ;; + esac +} + +# Get default Helix queue based on OS and architecture +get_default_queue() { + local os=$1 + local arch=$2 + + case "$os" in + linux) + case "$arch" in + x64) echo "Ubuntu.2204.Amd64.Open" ;; + arm64) echo "Ubuntu.2204.Arm64.Open" ;; + *) echo "Ubuntu.2204.Amd64.Open" ;; + esac + ;; + osx) + case "$arch" in + x64) echo "OSX.1200.Amd64.Open" ;; + arm64) echo "OSX.1200.Arm64.Open" ;; + *) echo "OSX.1200.Amd64.Open" ;; + esac + ;; + *) + echo "Ubuntu.2204.Amd64.Open" + ;; + esac +} + +show_help() { + cat << EOF + +Send diagnostics tests to Helix for remote execution. + +Usage: send-to-helix.sh [options] + +Options: + -configuration Build configuration (default: Debug) + -architecture Target architecture (default: x64) + -os Target OS (default: auto-detected) + -queue Helix queue to target (default: auto-selected based on OS) + -accesstoken Helix access token for internal queues + -creator Creator name for public builds + -bl Generate binary log + -help Show this help message + +Examples: + ./send-to-helix.sh + ./send-to-helix.sh -configuration Release -queue Ubuntu.2404.Amd64.Open + ./send-to-helix.sh -architecture arm64 -os linux + ./send-to-helix.sh -creator "MyName" -bl + +Notes: + - Run build.sh first to build the test artifacts + - For internal queues (not ending in .Open), provide -accesstoken + - Public queues require -creator to be set + +Available public Linux queues: + Ubuntu.2204.Amd64.Open + Ubuntu.2404.Amd64.Open + Ubuntu.2204.Arm64.Open + Debian.12.Amd64.Open + +Available public macOS queues: + OSX.1200.Amd64.Open + OSX.1200.Arm64.Open + OSX.1300.Amd64.Open + +EOF + exit 0 +} + +# Parse arguments +while [[ $# -gt 0 ]]; do + opt="$(echo "${1}" | tr '[:upper:]' '[:lower:]')" + case "$opt" in + -configuration|-c) + configuration="$2" + shift 2 + ;; + -architecture|-a) + architecture="$2" + shift 2 + ;; + -os) + target_os="$2" + shift 2 + ;; + -queue) + helix_queue="$2" + shift 2 + ;; + -accesstoken) + helix_access_token="$2" + shift 2 + ;; + -creator) + creator="$2" + shift 2 + ;; + -bl) + binary_log="/bl:$repo_root/artifacts/log/$configuration/SendToHelix.binlog" + shift + ;; + -help|-h|--help) + show_help + ;; + *) + echo "Unknown argument: $1" + show_help + ;; + esac +done + +# Auto-detect OS if not specified +if [[ -z "$target_os" ]]; then + target_os=$(detect_os) +fi + +# Auto-select queue if not specified +if [[ -z "$helix_queue" ]]; then + helix_queue=$(get_default_queue "$target_os" "$architecture") +fi + +# Set required environment variables for local Helix execution +export BUILD_SOURCEBRANCH="${BUILD_SOURCEBRANCH:-local}" +export BUILD_REPOSITORY_NAME="${BUILD_REPOSITORY_NAME:-diagnostics}" +export SYSTEM_TEAMPROJECT="${SYSTEM_TEAMPROJECT:-dnceng}" +export BUILD_REASON="${BUILD_REASON:-Manual}" + +# Build optional arguments +creator_arg="" +if [[ -n "$creator" ]]; then + creator_arg="/p:Creator=$creator" +fi + +access_token_arg="" +if [[ -n "$helix_access_token" ]]; then + access_token_arg="/p:HelixAccessToken=$helix_access_token" +fi + +echo "" +echo "===========================" +echo "Sending tests to Helix" +echo "===========================" +echo "Configuration: $configuration" +echo "Architecture: $architecture" +echo "Target OS: $target_os" +echo "Helix Queue: $helix_queue" +echo "Artifacts Dir: $repo_root/artifacts/" +echo "" + +# Verify artifacts exist +if [[ ! -d "$repo_root/artifacts/bin" ]]; then + echo "ERROR: Build artifacts not found at $repo_root/artifacts/bin" + echo "Please run build.sh first to build the tests." + exit 1 +fi + +# Send to Helix (use -tl:off to disable terminal logger for better output) +"$repo_root/eng/common/msbuild.sh" \ + "$repo_root/eng/helix.proj" \ + /restore \ + /t:Test \ + -tl:off \ + /p:Configuration="$configuration" \ + /p:TargetArchitecture="$architecture" \ + /p:TargetOS="$target_os" \ + /p:HelixTargetQueues="$helix_queue" \ + /p:TestArtifactsDir="$repo_root/artifacts/" \ + /p:EnableAzurePipelinesReporter=false \ + $access_token_arg \ + $creator_arg \ + $binary_log + +echo "" +echo "Tests submitted to Helix successfully!" +echo "View results at: https://helix.dot.net/" diff --git a/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs b/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs index 01821e3244..ccbd53dae2 100644 --- a/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs +++ b/src/Microsoft.Diagnostics.TestHelpers/TestConfiguration.cs @@ -38,6 +38,10 @@ private static TestRunConfiguration ParseDefaultConfigFile() private readonly DateTime _timestamp = DateTime.Now; + // Properties set from Helix environment variables that should not be overwritten + // by values in imported config files (e.g., Debugger.Tests.Common.txt). + private readonly HashSet _helixProtectedProperties = new(); + public IEnumerable Configurations { get; private set; } private void ParseConfigFile(string path) @@ -86,7 +90,35 @@ private void ParseConfigFile(string path) { initialConfig["WinDir"] = Path.GetFullPath(Environment.GetEnvironmentVariable("WINDIR")); } + + // On Helix, override ArtifactsDir and DotNetRoot before parsing config files + // so all $(ArtifactsDir) and $(DotNetRoot) references resolve to Helix paths. + // These are marked as protected so imported config files cannot overwrite them. + if (Environment.GetEnvironmentVariable("RunningOnHelix") == "true") + { + initialConfig["RunningOnHelix"] = "true"; + + string helixArtifactsDir = Environment.GetEnvironmentVariable("DIAGNOSTICS_ARTIFACTS_DIR"); + if (!string.IsNullOrEmpty(helixArtifactsDir)) + { + initialConfig["ArtifactsDir"] = helixArtifactsDir; + _helixProtectedProperties.Add("ArtifactsDir"); + } + + string helixDotNetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT"); + if (string.IsNullOrEmpty(helixDotNetRoot)) + { + helixDotNetRoot = Environment.GetEnvironmentVariable("DIAGNOSTICS_DOTNET_ROOT"); + } + if (!string.IsNullOrEmpty(helixDotNetRoot)) + { + initialConfig["DotNetRoot"] = helixDotNetRoot; + _helixProtectedProperties.Add("DotNetRoot"); + } + } + IEnumerable> configs = ParseConfigFile(path, new Dictionary[] { initialConfig }); + Configurations = configs.Select(c => new TestConfiguration(c)).ToList(); } @@ -179,6 +211,11 @@ private Dictionary[] ParseConfigSetting(Dictionary Date: Fri, 13 Feb 2026 11:02:43 -0500 Subject: [PATCH 06/48] move version defs to versions.props so they are defined in helix --- Directory.Build.props | 17 ----------- eng/Versions.props | 18 ++++++++++++ eng/helix.proj | 67 ++++++++++++++----------------------------- 3 files changed, 40 insertions(+), 62 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index c2fceffbab..02acad504c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -57,21 +57,4 @@ $(TargetRidOS)-$(TargetArch) - - net462 - - 8.0 - net$(NetCoreAppMinVersion) - - net8.0;net9.0;net10.0 - - net8.0 - - diff --git a/eng/Versions.props b/eng/Versions.props index 52988e350d..4f3961966d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -98,6 +98,24 @@ true -runtimesourcefeed '$(RuntimeSourceFeed)' -runtimesourcefeedkey '$(RuntimeSourceFeedKey)' + + + net462 + + 8.0 + net$(NetCoreAppMinVersion) + + net8.0;net9.0;net10.0 + + net8.0 + + $(MicrosoftNETCorePlatformsVersion) diff --git a/eng/helix.proj b/eng/helix.proj index 452633dc7d..2e0356e18a 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -45,7 +45,7 @@ true sdk - 10.0.102 + $([System.Text.RegularExpressions.Regex]::Match('$(MicrosoftNETSdkVersion)', '^\d+\.\d+\.\d+').Value) <_CorrelationPayload Condition="'$(TargetOS)' == 'Windows_NT'">%HELIX_CORRELATION_PAYLOAD% @@ -62,6 +62,10 @@ set "DIAGNOSTICS_ARTIFACTS_DIR=$(_ArtifactsDir)" && set "RunningOnHelix=true" && copy /Y "$(_VersionsFile)" "$(_DotNetCliDir)$(_PathSep)Debugger.Tests.Versions.txt" export DIAGNOSTICS_ARTIFACTS_DIR="$(_ArtifactsDir)" && export RunningOnHelix=true && cp -f "$(_VersionsFile)" "$(_DotNetCliDir)/Debugger.Tests.Versions.txt" + + + + <_VersionsStagingDir>$(ArtifactsDir)tmp\helix\dotnet-test\ @@ -82,26 +86,20 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + @@ -209,32 +207,11 @@ - - - - $(TestArtifactsDir)bin\%(HelixPureTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) - dotnet test %(HelixPureTestProject.Identity).dll --logger "trx;LogFileName=%(HelixPureTestProject.Identity).trx" --results-directory $(_UploadRoot) - $(TestTimeout) - - - - - - - $(TestArtifactsDir)bin\%(HelixComplexTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) - dotnet test %(HelixComplexTestProject.Identity).dll --logger "trx;LogFileName=%(HelixComplexTestProject.Identity).trx" --results-directory $(_UploadRoot) - $(TestTimeout) - - - - - - $(TestArtifactsDir)bin\%(HelixNativeTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) - dotnet test %(HelixNativeTestProject.Identity).dll --logger "trx;LogFileName=%(HelixNativeTestProject.Identity).trx" --results-directory $(_UploadRoot) + + $(TestArtifactsDir)bin\%(HelixTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) + dotnet test %(HelixTestProject.Identity).dll --logger "trx;LogFileName=$(_UploadRoot)\%(HelixTestProject.Identity).trx" $(TestTimeout) From ba1562403ed718ac514528ae878955b6029e15a9 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:03:01 -0500 Subject: [PATCH 07/48] update queues to use windows server 2022 --- eng/pipelines/global-variables.yml | 4 ++-- eng/send-to-helix.cmd | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index 3b5cadd6ef..99bdff7f53 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -79,9 +79,9 @@ variables: # Internal queues for official builds - ${{ if ne(variables['System.TeamProject'], 'public') }}: - name: HelixQueuesWindows_x64 - value: Windows.10.Amd64 + value: windows.amd64.server2022 - name: HelixQueuesWindows_x86 - value: Windows.10.Amd64 + value: windows.amd64.server2022 - name: HelixQueuesLinux_x64 value: Ubuntu.2204.Amd64 - name: HelixQueuesLinux_arm64 diff --git a/eng/send-to-helix.cmd b/eng/send-to-helix.cmd index cce321a0bd..c9cdde80a2 100644 --- a/eng/send-to-helix.cmd +++ b/eng/send-to-helix.cmd @@ -23,7 +23,7 @@ for %%i in ("%EngRoot%\..") do set "RepoRoot=%%~fi" set "Configuration=Debug" set "Architecture=x64" set "TargetOS=Windows_NT" -set "HelixQueue=Windows.10.Amd64" +set "HelixQueue=windows.amd64.server2022" set "HelixAccessToken=AAAE1Eq55IR3-s8xjJvkFcHtmI0" set "Creator=" set "BinaryLog=" From 9ce16943a65325e33bbf77aae0445d54e83d63bf Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:17:02 -0500 Subject: [PATCH 08/48] add check in CollectCommand to not crash if file is not created --- src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs b/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs index c72f43686c..4d74f8a95b 100644 --- a/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs +++ b/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs @@ -400,7 +400,8 @@ internal async Task Collect(CancellationToken ct, CommandLineConfiguration wroteStatus = true; } fileInfo.Refresh(); - ConsoleWriteLine($"[{stopwatch.Elapsed:dd\\:hh\\:mm\\:ss}]\tRecording trace {GetSize(fileInfo.Length)}"); + long fileLength = fileInfo.Exists ? fileInfo.Length : 0; + ConsoleWriteLine($"[{stopwatch.Elapsed:dd\\:hh\\:mm\\:ss}]\tRecording trace {GetSize(fileLength)}"); ConsoleWriteLine("Press or to exit..."); } From 925e9b961c3c065b9c82f0b2cbbc2cb5560ffe57 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 11:23:12 -0500 Subject: [PATCH 09/48] use helix in CI --- diagnostics.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diagnostics.yml b/diagnostics.yml index fa9efc693b..d89706d3d0 100644 --- a/diagnostics.yml +++ b/diagnostics.yml @@ -22,7 +22,7 @@ parameters: - name: useHelix displayName: Run tests on Helix (distributed testing) type: boolean - default: false + default: true trigger: none From 0835b43057406c7d5709ea7d3aef92d4423bc4f8 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 12:01:38 -0500 Subject: [PATCH 10/48] fix pipeline --- eng/pipelines/helix.yml | 46 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/eng/pipelines/helix.yml b/eng/pipelines/helix.yml index 53d9045f16..4b55e529b3 100644 --- a/eng/pipelines/helix.yml +++ b/eng/pipelines/helix.yml @@ -135,10 +135,29 @@ jobs: /p:HelixSource=$(_HelixSource) /p:HelixType=$(_HelixType) /p:HelixAccessToken=$(_HelixAccessToken) - ${{ if eq(parameters.isInternal, false) }}:/p:Creator=$(_Creator) /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: Send Tests to Helix + displayName: Send Tests to Helix (internal) + condition: and(succeeded(), eq('${{ parameters.isInternal }}', 'True')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - script: > + $(Build.SourcesDirectory)\eng\common\msbuild.cmd + $(Build.SourcesDirectory)\eng\helix.proj + /restore + /t:Test + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=$(_TargetOS) + /p:HelixTargetQueues=$(_HelixQueues) + /p:HelixSource=$(_HelixSource) + /p:HelixType=$(_HelixType) + /p:Creator=$(_Creator) + /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + displayName: Send Tests to Helix (public) + condition: and(succeeded(), ne('${{ parameters.isInternal }}', 'True')) env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -155,10 +174,29 @@ jobs: /p:HelixSource=$(_HelixSource) /p:HelixType=$(_HelixType) /p:HelixAccessToken=$(_HelixAccessToken) - ${{ if eq(parameters.isInternal, false) }}:/p:Creator=$(_Creator) /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: Send Tests to Helix + displayName: Send Tests to Helix (internal) + condition: and(succeeded(), eq('${{ parameters.isInternal }}', 'True')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /t:Test + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=$(_TargetOS) + /p:HelixTargetQueues=$(_HelixQueues) + /p:HelixSource=$(_HelixSource) + /p:HelixType=$(_HelixType) + /p:Creator=$(_Creator) + /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + displayName: Send Tests to Helix (public) + condition: and(succeeded(), ne('${{ parameters.isInternal }}', 'True')) env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) From 9bd642599b1ec604a8dbf9580a1e7c7087e6e518 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:08:06 -0500 Subject: [PATCH 11/48] refactor props to use Common.props --- Directory.Build.props | 16 +++++----- eng/AuxMsbuildFiles/Directory.Build.props | 1 + eng/Common.props | 38 +++++++++++++++++++++++ eng/Versions.props | 17 ---------- src/tests/Directory.Build.targets | 7 +++-- 5 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 eng/Common.props diff --git a/Directory.Build.props b/Directory.Build.props index 02acad504c..b92fa8c8f7 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,15 +4,6 @@ false - - false - Latest - 4 - true - true - <_SkipUpgradeNetAnalyzersNuGetWarning>true - - http://go.microsoft.com/fwlink/?LinkID=288859 git @@ -21,6 +12,13 @@ diagnostics + + + + + Latest + false + 4 + true + true + <_SkipUpgradeNetAnalyzersNuGetWarning>true + + net462 + + 8.0 + net$(NetCoreAppMinVersion) + + net8.0;net9.0;net10.0 + + net8.0 + + diff --git a/eng/Versions.props b/eng/Versions.props index 4f3961966d..fd526a554a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,23 +99,6 @@ -runtimesourcefeed '$(RuntimeSourceFeed)' -runtimesourcefeedkey '$(RuntimeSourceFeedKey)' - - net462 - - 8.0 - net$(NetCoreAppMinVersion) - - net8.0;net9.0;net10.0 - - net8.0 - - $(MicrosoftNETCorePlatformsVersion) diff --git a/src/tests/Directory.Build.targets b/src/tests/Directory.Build.targets index 9061e8ca91..8ee633b6fb 100644 --- a/src/tests/Directory.Build.targets +++ b/src/tests/Directory.Build.targets @@ -35,14 +35,17 @@ <_AuxDir>$(ArtifactsDir)test/AuxMsbuildFiles/ + From d129cc91abb2a356ad31d3cd6c62e51d59e07a00 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:08:27 -0500 Subject: [PATCH 12/48] refactor race condition fix for dotnet trace unittests --- src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs | 3 +-- src/tests/dotnet-trace/CollectCommandFunctionalTests.cs | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs b/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs index 4d74f8a95b..c72f43686c 100644 --- a/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs +++ b/src/Tools/dotnet-trace/CommandLine/Commands/CollectCommand.cs @@ -400,8 +400,7 @@ internal async Task Collect(CancellationToken ct, CommandLineConfiguration wroteStatus = true; } fileInfo.Refresh(); - long fileLength = fileInfo.Exists ? fileInfo.Length : 0; - ConsoleWriteLine($"[{stopwatch.Elapsed:dd\\:hh\\:mm\\:ss}]\tRecording trace {GetSize(fileLength)}"); + ConsoleWriteLine($"[{stopwatch.Elapsed:dd\\:hh\\:mm\\:ss}]\tRecording trace {GetSize(fileInfo.Length)}"); ConsoleWriteLine("Press or to exit..."); } diff --git a/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs b/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs index 634834b07c..a0a4b076d3 100644 --- a/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs +++ b/src/tests/dotnet-trace/CollectCommandFunctionalTests.cs @@ -91,6 +91,10 @@ public async Task CollectCommand_InvalidProcessSpecifierConfigurations(CollectAr private static async Task RunAsync(CollectArgs config, MockConsole console, bool hasChildProcess = false) { + // Suppress timing-dependent status output (e.g. "Recording trace 0.00 (B)") + // so tests can validate provider configuration output deterministically. + console.IsOutputRedirected = true; + var handler = new CollectCommandHandler(console); handler.StartTraceSessionAsync = (client, cfg, ct) => Task.FromResult(new TestCollectSession()); handler.ResumeRuntimeAsync = (client, ct) => Task.CompletedTask; From 810fe9ef37c11462496b769dbfdfdd67813aa7c8 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:08:42 -0500 Subject: [PATCH 13/48] update pipelines --- diagnostics.yml | 109 +++++++++-------------------- eng/pipelines/global-variables.yml | 4 ++ eng/pipelines/helix.yml | 43 ++++++------ 3 files changed, 59 insertions(+), 97 deletions(-) diff --git a/diagnostics.yml b/diagnostics.yml index d89706d3d0..854f809872 100644 --- a/diagnostics.yml +++ b/diagnostics.yml @@ -56,7 +56,7 @@ extends: parameters: stages: - stage: build - displayName: Build and Test Diagnostics + displayName: Build Diagnostics jobs: ############################ @@ -83,7 +83,7 @@ extends: jobTemplate: ${{ variables.jobTemplate }} name: Windows osGroup: Windows_NT - buildOnly: ${{ parameters.buildOnly }} + buildOnly: true buildConfigs: - configuration: Debug architecture: x64 @@ -138,7 +138,7 @@ extends: parameters: jobTemplate: ${{ variables.jobTemplate }} osGroup: MacOS - buildOnly: ${{ parameters.buildOnly }} + buildOnly: true buildConfigs: - configuration: Release architecture: x64 @@ -218,84 +218,15 @@ extends: ############################ # # - # Test only legs # + # Helix Test Stage # # # ############################ - - ${{ if ne(parameters.buildOnly, true) }}: - - template: /eng/pipelines/build.yml - parameters: - jobTemplate: ${{ variables.jobTemplate }} - name: Ubuntu_22_04 - osGroup: Linux - container: test_ubuntu_22_04 - dependsOn: Linux - testOnly: true - buildConfigs: - - configuration: Release - architecture: x64 - - ${{ if in(variables['Build.Reason'], 'PullRequest') }}: - - configuration: Debug - architecture: x64 - - - template: /eng/pipelines/build.yml - parameters: - jobTemplate: ${{ variables.jobTemplate }} - name: Alpine3_19 - osGroup: Linux - osSuffix: -musl - container: test_linux_musl_x64 - dependsOn: Linux_musl - testOnly: true - disableComponentGovernance: true - buildConfigs: - - configuration: Release - architecture: x64 - - ${{ if in(variables['Build.Reason'], 'PullRequest') }}: - - configuration: Debug - architecture: x64 - - - ${{ if ne(variables['System.TeamProject'], 'public') }}: - - template: /eng/pipelines/build.yml - parameters: - jobTemplate: ${{ variables.jobTemplate }} - name: Debian_Bullseye - osGroup: Linux - container: test_debian_11_amd64 - dependsOn: Linux - testOnly: true - buildConfigs: - - configuration: Release - architecture: x64 - - ${{ if in(variables['Build.Reason'], 'PullRequest') }}: - - configuration: Debug - architecture: x64 - - - template: /eng/pipelines/build.yml - parameters: - jobTemplate: ${{ variables.jobTemplate }} - name: Fedora_39 - osGroup: Linux - container: test_fedora - dependsOn: Linux - testOnly: true - buildConfigs: - - configuration: Release - architecture: x64 - - ${{ if in(variables['Build.Reason'], 'PullRequest') }}: - - configuration: Debug - architecture: x64 - - ############################ - # # - # Helix Test Stage # - # # - ############################ - - ${{ if and(eq(parameters.useHelix, true), ne(parameters.buildOnly, true)) }}: - stage: helix displayName: Run Tests on Helix dependsOn: build + condition: not(canceled()) jobs: # Windows x64 Helix tests - template: /eng/pipelines/helix.yml @@ -333,11 +264,37 @@ extends: isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} dependsOn: MacOS_x64_Release + # Windows arm64 Helix tests + - template: /eng/pipelines/helix.yml + parameters: + name: Helix_Windows + jobTemplate: ${{ variables.jobTemplate }} + osGroup: Windows_NT + configuration: Release + architecture: arm64 + helixQueues: $(HelixQueuesWindows_arm64) + isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} + dependsOn: Windows_arm64_Release + + # Linux arm64 Helix tests + - template: /eng/pipelines/helix.yml + parameters: + name: Helix_Linux + jobTemplate: ${{ variables.jobTemplate }} + osGroup: Linux + configuration: Release + architecture: arm64 + helixQueues: $(HelixQueuesLinux_arm64) + isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} + dependsOn: Linux_arm64_Release + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - stage: package displayName: Package, Sign, and Generate BAR Manifests - ${{ if eq(parameters.useHelix, true) }}: - dependsOn: helix + ${{ if and(eq(parameters.useHelix, true), ne(parameters.buildOnly, true)) }}: + dependsOn: + - build + - helix ${{ else }}: dependsOn: build jobs: diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index 99bdff7f53..53522d8c02 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -65,6 +65,8 @@ variables: value: Windows.10.Amd64.Open - name: HelixQueuesWindows_x86 value: Windows.10.Amd64.Open + - name: HelixQueuesWindows_arm64 + value: Windows.11.Arm64.Open - name: HelixQueuesLinux_x64 value: Ubuntu.2204.Amd64.Open - name: HelixQueuesLinux_arm64 @@ -82,6 +84,8 @@ variables: value: windows.amd64.server2022 - name: HelixQueuesWindows_x86 value: windows.amd64.server2022 + - name: HelixQueuesWindows_arm64 + value: windows.11.arm64 - name: HelixQueuesLinux_x64 value: Ubuntu.2204.Amd64 - name: HelixQueuesLinux_arm64 diff --git a/eng/pipelines/helix.yml b/eng/pipelines/helix.yml index 4b55e529b3..1166f95d2c 100644 --- a/eng/pipelines/helix.yml +++ b/eng/pipelines/helix.yml @@ -1,5 +1,6 @@ # Pipeline template for running tests on Helix -# This template sends test workloads to Helix machines for distributed execution +# This template downloads build artifacts and sends test workloads to Helix +# machines for distributed execution. parameters: # Job name suffix @@ -47,7 +48,7 @@ parameters: type: number default: 120 - # Job dependencies (build job name without architecture/configuration suffix) + # Job dependency name for artifact download (e.g. Windows_x64_Release) - name: dependsOn type: string default: '' @@ -63,11 +64,7 @@ jobs: name: ${{ parameters.name }}_${{ parameters.architecture }}_${{ parameters.configuration }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} templateContext: ${{ parameters.templateContext }} - - # Note: cross-stage job dependencies are not supported in Azure Pipelines. - # The stage-level dependsOn handles this. We keep dependsOn parameter for - # artifact naming only. - + pool: ${{ if eq(parameters.osGroup, 'Windows_NT') }}: name: $(BuildPool) @@ -90,7 +87,7 @@ jobs: variables: - _BuildConfig: ${{ parameters.configuration }} - _HelixType: test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - + # Determine target OS for helix.proj - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - _TargetOS: Windows_NT @@ -98,10 +95,16 @@ jobs: - _TargetOS: linux - ${{ if eq(parameters.osGroup, 'MacOS') }}: - _TargetOS: osx - + + # Build script + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - _buildScript: $(Build.SourcesDirectory)\build.cmd + - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: + - _buildScript: $(Build.SourcesDirectory)/build.sh + # Helix queue configuration - _HelixQueues: ${{ parameters.helixQueues }} - + # For internal builds, use the Helix access token - ${{ if eq(parameters.isInternal, true) }}: - group: DotNet-HelixApi-Access @@ -113,13 +116,15 @@ jobs: - _Creator: $(Build.RequestedFor) steps: - # Download build artifacts from the build job - - task: DownloadPipelineArtifact@2 - displayName: 'Download Build Artifacts' - inputs: - targetPath: '$(Build.SourcesDirectory)/artifacts' - artifactName: Build_${{ parameters.dependsOn }} - checkDownloadedFiles: true + # Build locally (build-only, no tests) to produce test assemblies and artifacts + - script: $(_buildScript) + -ci + -binaryLog + -configuration ${{ parameters.configuration }} + -architecture ${{ parameters.architecture }} + /p:OfficialBuildId=$(BUILD.BUILDNUMBER) + displayName: Build + condition: succeeded() # Send tests to Helix - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: @@ -135,7 +140,6 @@ jobs: /p:HelixSource=$(_HelixSource) /p:HelixType=$(_HelixType) /p:HelixAccessToken=$(_HelixAccessToken) - /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog displayName: Send Tests to Helix (internal) condition: and(succeeded(), eq('${{ parameters.isInternal }}', 'True')) @@ -154,7 +158,6 @@ jobs: /p:HelixSource=$(_HelixSource) /p:HelixType=$(_HelixType) /p:Creator=$(_Creator) - /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog displayName: Send Tests to Helix (public) condition: and(succeeded(), ne('${{ parameters.isInternal }}', 'True')) @@ -174,7 +177,6 @@ jobs: /p:HelixSource=$(_HelixSource) /p:HelixType=$(_HelixType) /p:HelixAccessToken=$(_HelixAccessToken) - /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog displayName: Send Tests to Helix (internal) condition: and(succeeded(), eq('${{ parameters.isInternal }}', 'True')) @@ -193,7 +195,6 @@ jobs: /p:HelixSource=$(_HelixSource) /p:HelixType=$(_HelixType) /p:Creator=$(_Creator) - /p:TestArtifactsDir=$(Build.SourcesDirectory)/artifacts/ /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog displayName: Send Tests to Helix (public) condition: and(succeeded(), ne('${{ parameters.isInternal }}', 'True')) From 4f57f9adf00071a41e88f691cddf60256051cced Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:53:25 -0500 Subject: [PATCH 14/48] update pipelines --- diagnostics.yml | 107 +++----------- eng/pipelines/build.yml | 85 ++++------- eng/pipelines/global-variables.yml | 12 +- eng/pipelines/helix.yml | 222 ----------------------------- eng/pipelines/send-to-helix.yml | 138 ++++++++++++++++++ 5 files changed, 193 insertions(+), 371 deletions(-) delete mode 100644 eng/pipelines/helix.yml create mode 100644 eng/pipelines/send-to-helix.yml diff --git a/diagnostics.yml b/diagnostics.yml index 854f809872..1d74c38f4d 100644 --- a/diagnostics.yml +++ b/diagnostics.yml @@ -83,7 +83,9 @@ extends: jobTemplate: ${{ variables.jobTemplate }} name: Windows osGroup: Windows_NT - buildOnly: true + buildOnly: ${{ parameters.buildOnly }} + useHelix: ${{ parameters.useHelix }} + helixQueues: $(HelixQueuesWindows_x64) buildConfigs: - configuration: Debug architecture: x64 @@ -104,7 +106,9 @@ extends: osGroup: Linux container: linux_x64 crossBuild: true - buildOnly: true + buildOnly: ${{ parameters.buildOnly }} + useHelix: ${{ parameters.useHelix }} + helixQueues: $(HelixQueuesLinux_x64) buildConfigs: - configuration: Release architecture: x64 @@ -122,7 +126,9 @@ extends: osSuffix: -musl container: linux_musl_x64 crossBuild: true - buildOnly: true + buildOnly: ${{ parameters.buildOnly }} + useHelix: ${{ parameters.useHelix }} + helixQueues: $(HelixQueuesLinux_musl_x64) buildConfigs: - configuration: Release architecture: x64 @@ -138,7 +144,9 @@ extends: parameters: jobTemplate: ${{ variables.jobTemplate }} osGroup: MacOS - buildOnly: true + buildOnly: ${{ parameters.buildOnly }} + useHelix: ${{ parameters.useHelix }} + helixQueues: $(HelixQueuesMacOS_x64) buildConfigs: - configuration: Release architecture: x64 @@ -152,7 +160,9 @@ extends: jobTemplate: ${{ variables.jobTemplate }} osGroup: MacOS crossBuild: true - buildOnly: true + buildOnly: ${{ parameters.buildOnly }} + useHelix: ${{ parameters.useHelix }} + helixQueues: $(HelixQueuesMacOS_arm64) buildConfigs: - configuration: Release architecture: arm64 @@ -180,7 +190,9 @@ extends: osGroup: Linux container: linux_arm64 crossBuild: true - buildOnly: true + buildOnly: ${{ parameters.buildOnly }} + useHelix: ${{ parameters.useHelix }} + helixQueues: $(HelixQueuesLinux_arm64) buildConfigs: - configuration: Release architecture: arm64 @@ -209,94 +221,19 @@ extends: osSuffix: -musl container: linux_musl_arm64 crossBuild: true - buildOnly: true + buildOnly: ${{ parameters.buildOnly }} + useHelix: ${{ parameters.useHelix }} + helixQueues: $(HelixQueuesLinux_musl_arm64) buildConfigs: - configuration: Release architecture: arm64 artifactUploadPath: bin/linux.arm64.Release artifactTargetPath: bin/linux-musl.arm64.Release - ############################ - # # - # Helix Test Stage # - # # - ############################ - - - ${{ if and(eq(parameters.useHelix, true), ne(parameters.buildOnly, true)) }}: - - stage: helix - displayName: Run Tests on Helix - dependsOn: build - condition: not(canceled()) - jobs: - # Windows x64 Helix tests - - template: /eng/pipelines/helix.yml - parameters: - name: Helix_Windows - jobTemplate: ${{ variables.jobTemplate }} - osGroup: Windows_NT - configuration: Release - architecture: x64 - helixQueues: $(HelixQueuesWindows_x64) - isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} - dependsOn: Windows_x64_Release - - # Linux x64 Helix tests - - template: /eng/pipelines/helix.yml - parameters: - name: Helix_Linux - jobTemplate: ${{ variables.jobTemplate }} - osGroup: Linux - configuration: Release - architecture: x64 - helixQueues: $(HelixQueuesLinux_x64) - isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} - dependsOn: Linux_x64_Release - - # MacOS x64 Helix tests - - template: /eng/pipelines/helix.yml - parameters: - name: Helix_MacOS - jobTemplate: ${{ variables.jobTemplate }} - osGroup: MacOS - configuration: Release - architecture: x64 - helixQueues: $(HelixQueuesMacOS_x64) - isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} - dependsOn: MacOS_x64_Release - - # Windows arm64 Helix tests - - template: /eng/pipelines/helix.yml - parameters: - name: Helix_Windows - jobTemplate: ${{ variables.jobTemplate }} - osGroup: Windows_NT - configuration: Release - architecture: arm64 - helixQueues: $(HelixQueuesWindows_arm64) - isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} - dependsOn: Windows_arm64_Release - - # Linux arm64 Helix tests - - template: /eng/pipelines/helix.yml - parameters: - name: Helix_Linux - jobTemplate: ${{ variables.jobTemplate }} - osGroup: Linux - configuration: Release - architecture: arm64 - helixQueues: $(HelixQueuesLinux_arm64) - isInternal: ${{ ne(variables['System.TeamProject'], 'public') }} - dependsOn: Linux_arm64_Release - - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - stage: package displayName: Package, Sign, and Generate BAR Manifests - ${{ if and(eq(parameters.useHelix, true), ne(parameters.buildOnly, true)) }}: - dependsOn: - - build - - helix - ${{ else }}: - dependsOn: build + dependsOn: build jobs: - template: /eng/common/templates-official/job/job.yml parameters: diff --git a/eng/pipelines/build.yml b/eng/pipelines/build.yml index ba061cc2f2..d144caadd5 100644 --- a/eng/pipelines/build.yml +++ b/eng/pipelines/build.yml @@ -50,25 +50,16 @@ parameters: type: string default: '' - # Optional: build only job if true + # Optional: build only, skip tests - name: buildOnly type: boolean default: false - # Optional: test only job if true -- name: testOnly - type: boolean - default: false - # Optional: architecture cross build if true - name: crossBuild type: boolean default: false -- name: dependsOn - type: string - default: '' - - name: isCodeQLRun type: boolean default: false @@ -77,6 +68,16 @@ parameters: type: boolean default: false + # Send tests to Helix for distributed execution +- name: useHelix + type: boolean + default: false + + # Helix queue to target (required when useHelix is true) +- name: helixQueues + type: string + default: '' + jobs: - ${{ each config in parameters.buildConfigs }}: - template: ${{ parameters.jobTemplate }} @@ -118,9 +119,6 @@ jobs: ${{ if ne(parameters.strategy, '') }}: 'error, we can no longer support the strategy feature in the new pipeline system. Please remove the strategy from the job template.': error - ${{ if ne(parameters.dependsOn, '') }}: - dependsOn: ${{ parameters.dependsOn }}_${{ config.architecture }}_${{ config.configuration }} - workspace: clean: all @@ -130,7 +128,6 @@ jobs: - _PhaseName: ${{ coalesce(parameters.name, parameters.osGroup) }}_${{ config.architecture }}_${{ config.configuration }} - _Pipeline_StreamDumpDir: $(Build.SourcesDirectory)/artifacts/tmp/${{ config.configuration }}/streams - - _TestArgs: '-test' - _Cross: '' - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: @@ -138,15 +135,6 @@ jobs: - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - _buildScript: $(Build.SourcesDirectory)/build.sh - - ${{ if and(eq(parameters.testOnly, 'true'), eq(parameters.buildOnly, 'true')) }}: - 'error, testOnly and buildOnly cannot be true at the same time': error - - - ${{ if eq(parameters.testOnly, 'true') }}: - - _TestArgs: '-test -skipnative' - - - ${{ if or(eq(parameters.buildOnly, 'true'), eq(parameters.isCodeQLRun, 'true')) }}: - - _TestArgs: '' - # For testing msrc's and service releases. The RuntimeSourceVersion is either "default" or the service release version to test - _InternalInstallArgs: '' - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.isCodeQLRun, 'false')) }}: @@ -160,22 +148,11 @@ jobs: - ${{ if eq(parameters.crossBuild, true) }}: - _Cross: -cross - steps: - - ${{ if eq(parameters.testOnly, true) }}: - - ${{ if ne(parameters.osGroup, 'Linux') }}: - - 'error, testOnly is only supported on Linux': error - - task: DownloadPipelineArtifact@2 - displayName: 'Download Build Artifacts' - inputs: - targetPath: '$(Build.ArtifactStagingDirectory)/__download__' - itemPattern: Build_${{ parameters.dependsOn }}_${{ config.architecture }}_${{ config.configuration }}/bin/** - checkDownloadedFiles: true - - task: CopyFiles@2 - displayName: 'Binplace Downloaded Product' - inputs: - sourceFolder: $(Build.ArtifactStagingDirectory)/__download__/Build_${{ parameters.dependsOn }}_${{ config.architecture }}_${{ config.configuration }}/bin/linux${{ parameters.osSuffix }}.${{ config.architecture }}.${{ config.configuration }} - targetFolder: '$(Build.SourcesDirectory)/artifacts/bin/linux.${{ config.architecture }}.${{ config.configuration }}' + # Helix variable group (only when useHelix is true, for internal builds) + - ${{ if and(eq(parameters.useHelix, true), ne(variables['System.TeamProject'], 'public')) }}: + - group: DotNet-HelixApi-Access + steps: - ${{ if eq(parameters.isCodeQLRun, 'true') }}: - task: CodeQL3000Init@0 displayName: CodeQL Initialize @@ -185,22 +162,25 @@ jobs: -binaryLog -configuration ${{ config.configuration }} -architecture ${{ config.architecture }} - $(_TestArgs) $(_Cross) $(_InternalInstallArgs) /p:OfficialBuildId=$(BUILD.BUILDNUMBER) - ${{ if eq(parameters.testOnly, 'true') }}: - displayName: Test - ${{ elseif eq(parameters.buildOnly, 'true') }}: - displayName: Build - ${{ else }}: - displayName: Build / Test + displayName: Build condition: succeeded() - ${{ if eq(parameters.isCodeQLRun, 'true') }}: - task: CodeQL3000Finalize@0 displayName: CodeQL Finalize + # Send tests to Helix (when useHelix is true and not buildOnly) + - ${{ if and(eq(parameters.useHelix, true), ne(parameters.buildOnly, true)) }}: + - template: /eng/pipelines/send-to-helix.yml@self + parameters: + configuration: ${{ config.configuration }} + architecture: ${{ config.architecture }} + osGroup: ${{ parameters.osGroup }} + helixQueues: ${{ parameters.helixQueues }} + - ${{ if ne(config.artifactUploadPath, '') }}: - task: CopyFiles@2 displayName: Gather binaries for publish @@ -258,18 +238,3 @@ jobs: sbomEnabled: false # we don't need SBOM for logs continueOnError: true condition: always() - - - ${{ if and(ne(parameters.buildOnly, 'true'), ne(parameters.isCodeQLRun, 'true')) }}: - # Publish test results to Azure Pipelines - - task: PublishTestResults@2 - inputs: - testResultsFormat: xUnit - testResultsFiles: '**/*.xml' - searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults' - testRunTitle: 'Tests $(_PhaseName)' - failTaskOnFailedTests: true - publishRunAttachments: true - mergeTestResults: true - buildConfiguration: ${{ config.configuration }} - continueOnError: true - condition: always() diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index 53522d8c02..439515f083 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -71,12 +71,14 @@ variables: value: Ubuntu.2204.Amd64.Open - name: HelixQueuesLinux_arm64 value: Ubuntu.2204.Arm64.Open + - name: HelixQueuesLinux_musl_x64 + value: Ubuntu.2204.Amd64.Open + - name: HelixQueuesLinux_musl_arm64 + value: Ubuntu.2204.Arm64.Open - name: HelixQueuesMacOS_x64 value: OSX.1200.Amd64.Open - name: HelixQueuesMacOS_arm64 value: OSX.1200.Arm64.Open - - name: HelixQueuesFreeBSD - value: '' # Internal queues for official builds - ${{ if ne(variables['System.TeamProject'], 'public') }}: @@ -90,9 +92,11 @@ variables: value: Ubuntu.2204.Amd64 - name: HelixQueuesLinux_arm64 value: Ubuntu.2204.Arm64 + - name: HelixQueuesLinux_musl_x64 + value: Ubuntu.2204.Amd64 + - name: HelixQueuesLinux_musl_arm64 + value: Ubuntu.2204.Arm64 - name: HelixQueuesMacOS_x64 value: OSX.1200.Amd64 - name: HelixQueuesMacOS_arm64 value: OSX.1200.Arm64 - - name: HelixQueuesFreeBSD - value: '' diff --git a/eng/pipelines/helix.yml b/eng/pipelines/helix.yml deleted file mode 100644 index 1166f95d2c..0000000000 --- a/eng/pipelines/helix.yml +++ /dev/null @@ -1,222 +0,0 @@ -# Pipeline template for running tests on Helix -# This template downloads build artifacts and sends test workloads to Helix -# machines for distributed execution. - -parameters: - # Job name suffix -- name: name - type: string - default: 'Helix' - -- name: jobTemplate - type: string - default: /eng/common/templates/job/job.yml@self - values: - - /eng/common/templates-official/job/job.yml@self - - /eng/common/templates/job/job.yml@self - -- name: osGroup - type: string - default: Windows_NT - values: - - Windows_NT - - Linux - - MacOS - - # Build configuration -- name: configuration - type: string - default: Debug - - # Target architecture -- name: architecture - type: string - default: x64 - - # Helix queue to target (semicolon-delimited list supported) -- name: helixQueues - type: string - default: '' - - # Whether this is an internal (authenticated) build -- name: isInternal - type: boolean - default: false - - # Job timeout -- name: timeoutInMinutes - type: number - default: 120 - - # Job dependency name for artifact download (e.g. Windows_x64_Release) -- name: dependsOn - type: string - default: '' - - # Template context for 1ES pipeline -- name: templateContext - type: object - default: {} - -jobs: -- template: ${{ parameters.jobTemplate }} - parameters: - name: ${{ parameters.name }}_${{ parameters.architecture }}_${{ parameters.configuration }} - timeoutInMinutes: ${{ parameters.timeoutInMinutes }} - templateContext: ${{ parameters.templateContext }} - - pool: - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - name: $(BuildPool) - demands: ImageOverride -equals $(WindowsImage) - os: windows - - ${{ if eq(parameters.osGroup, 'Linux') }}: - name: $(BuildPool) - demands: ImageOverride -equals $(LinuxImage) - os: linux - - ${{ if eq(parameters.osGroup, 'MacOS') }}: - name: Azure Pipelines - vmImage: $(macOSImage) - os: macOS - - workspace: - clean: all - - variables: - - _BuildConfig: ${{ parameters.configuration }} - - _HelixType: test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - - # Determine target OS for helix.proj - - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - - _TargetOS: Windows_NT - - ${{ if eq(parameters.osGroup, 'Linux') }}: - - _TargetOS: linux - - ${{ if eq(parameters.osGroup, 'MacOS') }}: - - _TargetOS: osx - - # Build script - - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - - _buildScript: $(Build.SourcesDirectory)\build.cmd - - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - - _buildScript: $(Build.SourcesDirectory)/build.sh - - # Helix queue configuration - - _HelixQueues: ${{ parameters.helixQueues }} - - # For internal builds, use the Helix access token - - ${{ if eq(parameters.isInternal, true) }}: - - group: DotNet-HelixApi-Access - - _HelixAccessToken: $(HelixApiAccessToken) - - _HelixSource: official/diagnostics/$(Build.SourceBranch) - - ${{ else }}: - - _HelixAccessToken: '' - - _HelixSource: pr/diagnostics/$(Build.SourceBranch) - - _Creator: $(Build.RequestedFor) - - steps: - # Build locally (build-only, no tests) to produce test assemblies and artifacts - - script: $(_buildScript) - -ci - -binaryLog - -configuration ${{ parameters.configuration }} - -architecture ${{ parameters.architecture }} - /p:OfficialBuildId=$(BUILD.BUILDNUMBER) - displayName: Build - condition: succeeded() - - # Send tests to Helix - - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - - script: > - $(Build.SourcesDirectory)\eng\common\msbuild.cmd - $(Build.SourcesDirectory)\eng\helix.proj - /restore - /t:Test - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=$(_TargetOS) - /p:HelixTargetQueues=$(_HelixQueues) - /p:HelixSource=$(_HelixSource) - /p:HelixType=$(_HelixType) - /p:HelixAccessToken=$(_HelixAccessToken) - /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: Send Tests to Helix (internal) - condition: and(succeeded(), eq('${{ parameters.isInternal }}', 'True')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - - script: > - $(Build.SourcesDirectory)\eng\common\msbuild.cmd - $(Build.SourcesDirectory)\eng\helix.proj - /restore - /t:Test - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=$(_TargetOS) - /p:HelixTargetQueues=$(_HelixQueues) - /p:HelixSource=$(_HelixSource) - /p:HelixType=$(_HelixType) - /p:Creator=$(_Creator) - /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: Send Tests to Helix (public) - condition: and(succeeded(), ne('${{ parameters.isInternal }}', 'True')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - - ${{ if ne(parameters.osGroup, 'Windows_NT') }}: - - script: > - $(Build.SourcesDirectory)/eng/common/msbuild.sh - $(Build.SourcesDirectory)/eng/helix.proj - /restore - /t:Test - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=$(_TargetOS) - /p:HelixTargetQueues=$(_HelixQueues) - /p:HelixSource=$(_HelixSource) - /p:HelixType=$(_HelixType) - /p:HelixAccessToken=$(_HelixAccessToken) - /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: Send Tests to Helix (internal) - condition: and(succeeded(), eq('${{ parameters.isInternal }}', 'True')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - - script: > - $(Build.SourcesDirectory)/eng/common/msbuild.sh - $(Build.SourcesDirectory)/eng/helix.proj - /restore - /t:Test - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=$(_TargetOS) - /p:HelixTargetQueues=$(_HelixQueues) - /p:HelixSource=$(_HelixSource) - /p:HelixType=$(_HelixType) - /p:Creator=$(_Creator) - /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: Send Tests to Helix (public) - condition: and(succeeded(), ne('${{ parameters.isInternal }}', 'True')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - # Publish Helix logs - - task: CopyFiles@2 - displayName: Gather Helix Logs - inputs: - sourceFolder: '$(Build.SourcesDirectory)/artifacts' - contents: 'log/**' - targetFolder: '$(Build.StagingDirectory)/HelixLogs' - continueOnError: true - condition: always() - - - template: /eng/pipelines/publish-pipeline-artifact-shim.yml@self - parameters: - displayName: Publish Helix Logs - inputs: - targetPath: '$(Build.StagingDirectory)/HelixLogs' - artifactName: HelixLogs_${{ parameters.name }}_${{ parameters.osGroup }}_${{ parameters.architecture }}_${{ parameters.configuration }} - sbomEnabled: false - continueOnError: true - condition: always() diff --git a/eng/pipelines/send-to-helix.yml b/eng/pipelines/send-to-helix.yml new file mode 100644 index 0000000000..a78ba9b28d --- /dev/null +++ b/eng/pipelines/send-to-helix.yml @@ -0,0 +1,138 @@ +# Step template for sending tests to Helix. +# This template is included by build.yml to send test workloads to Helix +# machines for distributed execution. +# +# Internal vs public is determined automatically by System.TeamProject: +# - Internal: uses HelixAccessToken from DotNet-HelixApi-Access variable group +# - Public: uses Creator for anonymous submission +# +# Prerequisites: The DotNet-HelixApi-Access variable group must be included +# at the job level for internal builds (provides HelixApiAccessToken). + +parameters: + # Build configuration (e.g. Debug, Release) +- name: configuration + type: string + + # Target architecture (e.g. x64, arm64) +- name: architecture + type: string + + # Target OS group +- name: osGroup + type: string + default: Windows_NT + values: + - Windows_NT + - Linux + - MacOS + + # Helix queue to target +- name: helixQueues + type: string + +steps: +- ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - script: > + $(Build.SourcesDirectory)\eng\common\msbuild.cmd + $(Build.SourcesDirectory)\eng\helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=Windows_NT + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=official/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:HelixAccessToken=$(HelixApiAccessToken) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix (internal) + condition: and(succeeded(), ne(variables['System.TeamProject'], 'public')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - script: > + $(Build.SourcesDirectory)\eng\common\msbuild.cmd + $(Build.SourcesDirectory)\eng\helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=Windows_NT + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:Creator=$(Build.RequestedFor) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix (public) + condition: and(succeeded(), eq(variables['System.TeamProject'], 'public')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + +- ${{ if eq(parameters.osGroup, 'Linux') }}: + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=linux + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=official/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:HelixAccessToken=$(HelixApiAccessToken) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix (internal) + condition: and(succeeded(), ne(variables['System.TeamProject'], 'public')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=linux + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:Creator=$(Build.RequestedFor) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix (public) + condition: and(succeeded(), eq(variables['System.TeamProject'], 'public')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + +- ${{ if eq(parameters.osGroup, 'MacOS') }}: + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=osx + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=official/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:HelixAccessToken=$(HelixApiAccessToken) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix (internal) + condition: and(succeeded(), ne(variables['System.TeamProject'], 'public')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=osx + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:Creator=$(Build.RequestedFor) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix (public) + condition: and(succeeded(), eq(variables['System.TeamProject'], 'public')) + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) From 88c490240645833ae9fd696a6fc815564f78023e Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 13:55:18 -0500 Subject: [PATCH 15/48] fix --- eng/pipelines/send-to-helix.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/pipelines/send-to-helix.yml b/eng/pipelines/send-to-helix.yml index a78ba9b28d..b44759f0b9 100644 --- a/eng/pipelines/send-to-helix.yml +++ b/eng/pipelines/send-to-helix.yml @@ -33,8 +33,8 @@ parameters: steps: - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - - script: > - $(Build.SourcesDirectory)\eng\common\msbuild.cmd + - powershell: > + & $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\helix.proj /restore /p:Configuration=${{ parameters.configuration }} @@ -50,8 +50,8 @@ steps: env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - script: > - $(Build.SourcesDirectory)\eng\common\msbuild.cmd + - powershell: > + & $(Build.SourcesDirectory)\eng\common\msbuild.ps1 $(Build.SourcesDirectory)\eng\helix.proj /restore /p:Configuration=${{ parameters.configuration }} From 98dec5210ae3ed1d14e9c8e2e4df85cd3c6beca0 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:27:26 -0500 Subject: [PATCH 16/48] update pipelines --- diagnostics.yml | 7 + eng/pipelines/build.yml | 6 + eng/pipelines/global-variables.yml | 8 +- eng/pipelines/send-to-helix.yml | 212 +++++++++++++++-------------- 4 files changed, 126 insertions(+), 107 deletions(-) diff --git a/diagnostics.yml b/diagnostics.yml index 1d74c38f4d..00b78f69cc 100644 --- a/diagnostics.yml +++ b/diagnostics.yml @@ -85,6 +85,7 @@ extends: osGroup: Windows_NT buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} + isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} helixQueues: $(HelixQueuesWindows_x64) buildConfigs: - configuration: Debug @@ -108,6 +109,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} + isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} helixQueues: $(HelixQueuesLinux_x64) buildConfigs: - configuration: Release @@ -128,6 +130,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} + isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} helixQueues: $(HelixQueuesLinux_musl_x64) buildConfigs: - configuration: Release @@ -146,6 +149,7 @@ extends: osGroup: MacOS buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} + isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} helixQueues: $(HelixQueuesMacOS_x64) buildConfigs: - configuration: Release @@ -162,6 +166,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} + isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} helixQueues: $(HelixQueuesMacOS_arm64) buildConfigs: - configuration: Release @@ -192,6 +197,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} + isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} helixQueues: $(HelixQueuesLinux_arm64) buildConfigs: - configuration: Release @@ -223,6 +229,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} + isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} helixQueues: $(HelixQueuesLinux_musl_arm64) buildConfigs: - configuration: Release diff --git a/eng/pipelines/build.yml b/eng/pipelines/build.yml index d144caadd5..fe890c3565 100644 --- a/eng/pipelines/build.yml +++ b/eng/pipelines/build.yml @@ -78,6 +78,11 @@ parameters: type: string default: '' + # Whether this is an official (non-PR, internal) build +- name: isOfficialBuild + type: boolean + default: false + jobs: - ${{ each config in parameters.buildConfigs }}: - template: ${{ parameters.jobTemplate }} @@ -180,6 +185,7 @@ jobs: architecture: ${{ config.architecture }} osGroup: ${{ parameters.osGroup }} helixQueues: ${{ parameters.helixQueues }} + isOfficialBuild: ${{ parameters.isOfficialBuild }} - ${{ if ne(config.artifactUploadPath, '') }}: - task: CopyFiles@2 diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index 439515f083..2cf8ed2a6b 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -59,8 +59,8 @@ variables: value: $(dotnetclimsrc-read-sas-token-base64) # Helix queue configuration -# Public (open) queues for PR validation -- ${{ if eq(variables['System.TeamProject'], 'public') }}: +# Public (open) queues for PR validation and public project builds +- ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: - name: HelixQueuesWindows_x64 value: Windows.10.Amd64.Open - name: HelixQueuesWindows_x86 @@ -80,8 +80,8 @@ variables: - name: HelixQueuesMacOS_arm64 value: OSX.1200.Arm64.Open -# Internal queues for official builds -- ${{ if ne(variables['System.TeamProject'], 'public') }}: +# Internal queues for official builds (non-PR, non-public) +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - name: HelixQueuesWindows_x64 value: windows.amd64.server2022 - name: HelixQueuesWindows_x86 diff --git a/eng/pipelines/send-to-helix.yml b/eng/pipelines/send-to-helix.yml index b44759f0b9..d7172ade5a 100644 --- a/eng/pipelines/send-to-helix.yml +++ b/eng/pipelines/send-to-helix.yml @@ -2,12 +2,12 @@ # This template is included by build.yml to send test workloads to Helix # machines for distributed execution. # -# Internal vs public is determined automatically by System.TeamProject: -# - Internal: uses HelixAccessToken from DotNet-HelixApi-Access variable group -# - Public: uses Creator for anonymous submission +# Official vs PR builds: +# - Official (isOfficialBuild=true): uses HelixAccessToken from DotNet-HelixApi-Access variable group +# - PR/public (isOfficialBuild=false): uses Creator for anonymous submission # # Prerequisites: The DotNet-HelixApi-Access variable group must be included -# at the job level for internal builds (provides HelixApiAccessToken). +# at the job level for official builds (provides HelixApiAccessToken). parameters: # Build configuration (e.g. Debug, Release) @@ -31,108 +31,114 @@ parameters: - name: helixQueues type: string + # Whether this is an official (non-PR, internal) build +- name: isOfficialBuild + type: boolean + default: false + steps: -- ${{ if eq(parameters.osGroup, 'Windows_NT') }}: - - powershell: > - & $(Build.SourcesDirectory)\eng\common\msbuild.ps1 - $(Build.SourcesDirectory)\eng\helix.proj - /restore - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=Windows_NT - /p:HelixTargetQueues=${{ parameters.helixQueues }} - /p:HelixSource=official/diagnostics/$(Build.SourceBranch) - /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - /p:HelixAccessToken=$(HelixApiAccessToken) - /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog - displayName: Send Tests to Helix (internal) - condition: and(succeeded(), ne(variables['System.TeamProject'], 'public')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) +# Official builds: use HelixAccessToken for internal queues +- ${{ if eq(parameters.isOfficialBuild, true) }}: + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - powershell: > + & $(Build.SourcesDirectory)\eng\common\msbuild.ps1 + $(Build.SourcesDirectory)\eng\helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=Windows_NT + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=official/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:HelixAccessToken=$(HelixApiAccessToken) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - powershell: > - & $(Build.SourcesDirectory)\eng\common\msbuild.ps1 - $(Build.SourcesDirectory)\eng\helix.proj - /restore - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=Windows_NT - /p:HelixTargetQueues=${{ parameters.helixQueues }} - /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) - /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - /p:Creator=$(Build.RequestedFor) - /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog - displayName: Send Tests to Helix (public) - condition: and(succeeded(), eq(variables['System.TeamProject'], 'public')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) + - ${{ if eq(parameters.osGroup, 'Linux') }}: + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=linux + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=official/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:HelixAccessToken=$(HelixApiAccessToken) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) -- ${{ if eq(parameters.osGroup, 'Linux') }}: - - script: > - $(Build.SourcesDirectory)/eng/common/msbuild.sh - $(Build.SourcesDirectory)/eng/helix.proj - /restore - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=linux - /p:HelixTargetQueues=${{ parameters.helixQueues }} - /p:HelixSource=official/diagnostics/$(Build.SourceBranch) - /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - /p:HelixAccessToken=$(HelixApiAccessToken) - /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog - displayName: Send Tests to Helix (internal) - condition: and(succeeded(), ne(variables['System.TeamProject'], 'public')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) + - ${{ if eq(parameters.osGroup, 'MacOS') }}: + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=osx + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=official/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:HelixAccessToken=$(HelixApiAccessToken) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - script: > - $(Build.SourcesDirectory)/eng/common/msbuild.sh - $(Build.SourcesDirectory)/eng/helix.proj - /restore - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=linux - /p:HelixTargetQueues=${{ parameters.helixQueues }} - /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) - /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - /p:Creator=$(Build.RequestedFor) - /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog - displayName: Send Tests to Helix (public) - condition: and(succeeded(), eq(variables['System.TeamProject'], 'public')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) +# PR/public builds: use Creator for anonymous submission +- ${{ else }}: + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - powershell: > + & $(Build.SourcesDirectory)\eng\common\msbuild.ps1 + $(Build.SourcesDirectory)\eng\helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=Windows_NT + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:Creator=$(Build.RequestedFor) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) -- ${{ if eq(parameters.osGroup, 'MacOS') }}: - - script: > - $(Build.SourcesDirectory)/eng/common/msbuild.sh - $(Build.SourcesDirectory)/eng/helix.proj - /restore - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=osx - /p:HelixTargetQueues=${{ parameters.helixQueues }} - /p:HelixSource=official/diagnostics/$(Build.SourceBranch) - /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - /p:HelixAccessToken=$(HelixApiAccessToken) - /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog - displayName: Send Tests to Helix (internal) - condition: and(succeeded(), ne(variables['System.TeamProject'], 'public')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) + - ${{ if eq(parameters.osGroup, 'Linux') }}: + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=linux + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:Creator=$(Build.RequestedFor) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - script: > - $(Build.SourcesDirectory)/eng/common/msbuild.sh - $(Build.SourcesDirectory)/eng/helix.proj - /restore - /p:Configuration=${{ parameters.configuration }} - /p:TargetArchitecture=${{ parameters.architecture }} - /p:TargetOS=osx - /p:HelixTargetQueues=${{ parameters.helixQueues }} - /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) - /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ - /p:Creator=$(Build.RequestedFor) - /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog - displayName: Send Tests to Helix (public) - condition: and(succeeded(), eq(variables['System.TeamProject'], 'public')) - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) + - ${{ if eq(parameters.osGroup, 'MacOS') }}: + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/eng/helix.proj + /restore + /p:Configuration=${{ parameters.configuration }} + /p:TargetArchitecture=${{ parameters.architecture }} + /p:TargetOS=osx + /p:HelixTargetQueues=${{ parameters.helixQueues }} + /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) + /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ + /p:Creator=$(Build.RequestedFor) + /bl:$(Build.SourcesDirectory)/artifacts/log/${{ parameters.configuration }}/SendToHelix.binlog + displayName: Send Tests to Helix + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) \ No newline at end of file From b56f0408e338c89ab95614cc7ef65c4c6bced258 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:31:18 -0500 Subject: [PATCH 17/48] clean up and fix pipeline --- eng/Versions.props | 1 - eng/pipelines/build.yml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index fd526a554a..52988e350d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -98,7 +98,6 @@ true -runtimesourcefeed '$(RuntimeSourceFeed)' -runtimesourcefeedkey '$(RuntimeSourceFeedKey)' - $(MicrosoftNETCorePlatformsVersion) diff --git a/eng/pipelines/build.yml b/eng/pipelines/build.yml index fe890c3565..922bedbcaa 100644 --- a/eng/pipelines/build.yml +++ b/eng/pipelines/build.yml @@ -153,8 +153,8 @@ jobs: - ${{ if eq(parameters.crossBuild, true) }}: - _Cross: -cross - # Helix variable group (only when useHelix is true, for internal builds) - - ${{ if and(eq(parameters.useHelix, true), ne(variables['System.TeamProject'], 'public')) }}: + # Helix variable group (only when useHelix is true, for official builds) + - ${{ if and(eq(parameters.useHelix, true), eq(parameters.isOfficialBuild, true)) }}: - group: DotNet-HelixApi-Access steps: From a8b13da744240830e01c8fa98503c443cc548e3e Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:41:48 -0500 Subject: [PATCH 18/48] fix macos queues --- eng/pipelines/global-variables.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index 2cf8ed2a6b..e05e8caf6c 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -76,9 +76,9 @@ variables: - name: HelixQueuesLinux_musl_arm64 value: Ubuntu.2204.Arm64.Open - name: HelixQueuesMacOS_x64 - value: OSX.1200.Amd64.Open + value: OSX.15.Amd64.Open - name: HelixQueuesMacOS_arm64 - value: OSX.1200.Arm64.Open + value: OSX.15.Arm64.Open # Internal queues for official builds (non-PR, non-public) - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: @@ -97,6 +97,6 @@ variables: - name: HelixQueuesLinux_musl_arm64 value: Ubuntu.2204.Arm64 - name: HelixQueuesMacOS_x64 - value: OSX.1200.Amd64 + value: OSX.15.Amd64 - name: HelixQueuesMacOS_arm64 - value: OSX.1200.Arm64 + value: OSX.15.Arm64 From 4dee5a4947c3244c2c499c49ad3cb10a5fbb2954 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:44:11 -0500 Subject: [PATCH 19/48] fix windows queues --- eng/pipelines/global-variables.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index e05e8caf6c..df7890b3b1 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -62,9 +62,9 @@ variables: # Public (open) queues for PR validation and public project builds - ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: - name: HelixQueuesWindows_x64 - value: Windows.10.Amd64.Open + value: windows.amd64.server2022 - name: HelixQueuesWindows_x86 - value: Windows.10.Amd64.Open + value: windows.amd64.server2022 - name: HelixQueuesWindows_arm64 value: Windows.11.Arm64.Open - name: HelixQueuesLinux_x64 From d905cd832ee777303d80f3d18dd143ed2e4374d9 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:13:15 -0500 Subject: [PATCH 20/48] update queues --- eng/pipelines/global-variables.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index df7890b3b1..b86041d451 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -62,9 +62,9 @@ variables: # Public (open) queues for PR validation and public project builds - ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: - name: HelixQueuesWindows_x64 - value: windows.amd64.server2022 + value: windows.11.amd64.client.Open - name: HelixQueuesWindows_x86 - value: windows.amd64.server2022 + value: windows.11.amd64.client.Open - name: HelixQueuesWindows_arm64 value: Windows.11.Arm64.Open - name: HelixQueuesLinux_x64 @@ -83,9 +83,9 @@ variables: # Internal queues for official builds (non-PR, non-public) - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - name: HelixQueuesWindows_x64 - value: windows.amd64.server2022 + value: windows.11.amd64.client - name: HelixQueuesWindows_x86 - value: windows.amd64.server2022 + value: windows.11.amd64.client - name: HelixQueuesWindows_arm64 value: windows.11.arm64 - name: HelixQueuesLinux_x64 From c0f048221568274445659946ebc4758d92f29e2c Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:24:15 -0500 Subject: [PATCH 21/48] update to match runtime logic --- diagnostics.yml | 14 +++++++------- eng/pipelines/global-variables.yml | 26 +++++++++++++------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/diagnostics.yml b/diagnostics.yml index 00b78f69cc..17112808d2 100644 --- a/diagnostics.yml +++ b/diagnostics.yml @@ -85,7 +85,7 @@ extends: osGroup: Windows_NT buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} - isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} + isOfficialBuild: ${{ eq(variables['System.TeamProject'], 'internal') }} helixQueues: $(HelixQueuesWindows_x64) buildConfigs: - configuration: Debug @@ -109,7 +109,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} - isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} + isOfficialBuild: ${{ eq(variables['System.TeamProject'], 'internal') }} helixQueues: $(HelixQueuesLinux_x64) buildConfigs: - configuration: Release @@ -130,7 +130,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} - isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} + isOfficialBuild: ${{ eq(variables['System.TeamProject'], 'internal') }} helixQueues: $(HelixQueuesLinux_musl_x64) buildConfigs: - configuration: Release @@ -149,7 +149,7 @@ extends: osGroup: MacOS buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} - isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} + isOfficialBuild: ${{ eq(variables['System.TeamProject'], 'internal') }} helixQueues: $(HelixQueuesMacOS_x64) buildConfigs: - configuration: Release @@ -166,7 +166,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} - isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} + isOfficialBuild: ${{ eq(variables['System.TeamProject'], 'internal') }} helixQueues: $(HelixQueuesMacOS_arm64) buildConfigs: - configuration: Release @@ -197,7 +197,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} - isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} + isOfficialBuild: ${{ eq(variables['System.TeamProject'], 'internal') }} helixQueues: $(HelixQueuesLinux_arm64) buildConfigs: - configuration: Release @@ -229,7 +229,7 @@ extends: crossBuild: true buildOnly: ${{ parameters.buildOnly }} useHelix: ${{ parameters.useHelix }} - isOfficialBuild: ${{ and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.DefinitionName'], 'dotnet-diagnostics')) }} + isOfficialBuild: ${{ eq(variables['System.TeamProject'], 'internal') }} helixQueues: $(HelixQueuesLinux_musl_arm64) buildConfigs: - configuration: Release diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index b86041d451..b1cc3b96c3 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -59,43 +59,43 @@ variables: value: $(dotnetclimsrc-read-sas-token-base64) # Helix queue configuration -# Public (open) queues for PR validation and public project builds -- ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: +# Public (open) queues +- ${{ if eq(variables['System.TeamProject'], 'public') }}: - name: HelixQueuesWindows_x64 - value: windows.11.amd64.client.Open + value: Windows.Amd64.Server2022.Open - name: HelixQueuesWindows_x86 - value: windows.11.amd64.client.Open + value: Windows.Amd64.Server2022.Open - name: HelixQueuesWindows_arm64 value: Windows.11.Arm64.Open - name: HelixQueuesLinux_x64 value: Ubuntu.2204.Amd64.Open - name: HelixQueuesLinux_arm64 - value: Ubuntu.2204.Arm64.Open + value: Ubuntu.2204.ArmArch.Open - name: HelixQueuesLinux_musl_x64 value: Ubuntu.2204.Amd64.Open - name: HelixQueuesLinux_musl_arm64 - value: Ubuntu.2204.Arm64.Open + value: Ubuntu.2204.ArmArch.Open - name: HelixQueuesMacOS_x64 value: OSX.15.Amd64.Open - name: HelixQueuesMacOS_arm64 value: OSX.15.Arm64.Open -# Internal queues for official builds (non-PR, non-public) -- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: +# Internal queues +- ${{ if eq(variables['System.TeamProject'], 'internal') }}: - name: HelixQueuesWindows_x64 - value: windows.11.amd64.client + value: Windows.Amd64.Server2022 - name: HelixQueuesWindows_x86 - value: windows.11.amd64.client + value: Windows.Amd64.Server2022 - name: HelixQueuesWindows_arm64 - value: windows.11.arm64 + value: Windows.11.Arm64 - name: HelixQueuesLinux_x64 value: Ubuntu.2204.Amd64 - name: HelixQueuesLinux_arm64 - value: Ubuntu.2204.Arm64 + value: Ubuntu.2204.ArmArch - name: HelixQueuesLinux_musl_x64 value: Ubuntu.2204.Amd64 - name: HelixQueuesLinux_musl_arm64 - value: Ubuntu.2204.Arm64 + value: Ubuntu.2204.ArmArch - name: HelixQueuesMacOS_x64 value: OSX.15.Amd64 - name: HelixQueuesMacOS_arm64 From 82c4cf8a20c2a41049625fee350ea21645fcc3a3 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:45:17 -0500 Subject: [PATCH 22/48] fix trx generation --- eng/helix.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/helix.proj b/eng/helix.proj index 2e0356e18a..32304d2ab2 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -211,7 +211,7 @@ $(TestArtifactsDir)bin\%(HelixTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) - dotnet test %(HelixTestProject.Identity).dll --logger "trx;LogFileName=$(_UploadRoot)\%(HelixTestProject.Identity).trx" + dotnet test %(HelixTestProject.Identity).dll --logger "trx;LogFileName=$(_UploadRoot)$(_PathSep)%(HelixTestProject.Identity).trx" $(TestTimeout) From 5865aa883f46ce97c775f712f08f9c98b3be4c67 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 10:41:45 -0500 Subject: [PATCH 23/48] update helix configs --- eng/helix.proj | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index 32304d2ab2..c39a159676 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -33,6 +33,7 @@ test/$(Configuration)/$(TargetArchitecture)/ $(BUILD_BUILDNUMBER) 0.0.0.0 + $(TargetOS)-$(Configuration)-$(TargetArchitecture)- $(ArtifactsDir) @@ -58,14 +59,36 @@ <_ArtifactsDir>$(_CorrelationPayload)$(_PathSep)artifacts$(_PathSep) <_VersionsFile>$(_ArtifactsDir)dotnet-test$(_PathSep)Debugger.Tests.Versions.txt - - set "DIAGNOSTICS_ARTIFACTS_DIR=$(_ArtifactsDir)" && set "RunningOnHelix=true" && copy /Y "$(_VersionsFile)" "$(_DotNetCliDir)$(_PathSep)Debugger.Tests.Versions.txt" - export DIAGNOSTICS_ARTIFACTS_DIR="$(_ArtifactsDir)" && export RunningOnHelix=true && cp -f "$(_VersionsFile)" "$(_DotNetCliDir)/Debugger.Tests.Versions.txt" + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + <_VersionsStagingDir>$(ArtifactsDir)tmp\helix\dotnet-test\ From 34528ffd5399e612f7ed66509b41d90cacd4eddc Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 13:16:59 -0500 Subject: [PATCH 24/48] modify precommands --- eng/helix.proj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eng/helix.proj b/eng/helix.proj index c39a159676..9fa7326580 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -88,6 +88,10 @@ + + @(HelixPreCommand) + + <_VersionsStagingDir>$(ArtifactsDir)tmp\helix\dotnet-test\ From 4b80d2a4a91e1bc5cf99b82aeec59e462d4bad45 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:03:40 -0500 Subject: [PATCH 25/48] make sure to target x86 on the x86 arch --- eng/helix.proj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/helix.proj b/eng/helix.proj index 9fa7326580..657edc096f 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -47,6 +47,8 @@ true sdk $([System.Text.RegularExpressions.Regex]::Match('$(MicrosoftNETSdkVersion)', '^\d+\.\d+\.\d+').Value) + + win-x86 <_CorrelationPayload Condition="'$(TargetOS)' == 'Windows_NT'">%HELIX_CORRELATION_PAYLOAD% From f54d70fa58c6456358593931162b8e150a736c2a Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:05:56 -0500 Subject: [PATCH 26/48] update name --- eng/helix.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/helix.proj b/eng/helix.proj index 657edc096f..27cdcc140b 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -33,7 +33,7 @@ test/$(Configuration)/$(TargetArchitecture)/ $(BUILD_BUILDNUMBER) 0.0.0.0 - $(TargetOS)-$(Configuration)-$(TargetArchitecture)- + $(TargetOS) $(TargetArchitecture) $(Configuration) @ $(ArtifactsDir) From ae3de630c1270d3e9bbdbc14c6189b47b518ec6f Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 14:10:02 -0500 Subject: [PATCH 27/48] enable DevToolsSecurity on OSX helix queues --- eng/helix.proj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eng/helix.proj b/eng/helix.proj index 27cdcc140b..5b206f0bea 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -78,6 +78,9 @@ + + + From bb29b536ca6b6100ba3fc9cce569ba317591e736 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 16:34:04 -0500 Subject: [PATCH 28/48] fix TMPDIR and macOS /tmp symlink resolution for Helix - Linux: Set TMPDIR=/tmp to ensure consistent diagnostic IPC socket paths (Helix agents may set TMPDIR to non-writable work item temp dirs) - macOS: Set TMPDIR=/private/tmp (resolved /tmp symlink) - macOS: Resolve HELIX_CORRELATION_PAYLOAD through /tmp -> /private/tmp symlink so all derived paths match what the runtime reports - macOS: Add ResolveMacOSDotNetRoot target to resolve DOTNET_ROOT after Helix SDK sets it (fixes BasicProcessInfoSuspendTest path mismatch) --- eng/helix.proj | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/eng/helix.proj b/eng/helix.proj index 5b206f0bea..0f1825d341 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -74,6 +74,12 @@ + + + + @@ -87,6 +93,8 @@ + + @@ -96,6 +104,15 @@ @(HelixPreCommand) + + + + + $(HelixPreCommands);export DOTNET_ROOT=$(python3 -c "import os; print(os.path.realpath('$DOTNET_ROOT'))") + + From ef54cbcac16a363cd1f23ae2fa847f3c5a6f597b Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:10:47 -0500 Subject: [PATCH 29/48] fix MSBuild escaping for shell command substitution on macOS MSBuild was interpreting \ as a property reference, resolving to empty. Use %24 to escape the dollar sign so MSBuild emits a literal \ for shell command substitution. --- eng/helix.proj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index 0f1825d341..3e7042cd93 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -79,7 +79,7 @@ - + @@ -110,7 +110,7 @@ - $(HelixPreCommands);export DOTNET_ROOT=$(python3 -c "import os; print(os.path.realpath('$DOTNET_ROOT'))") + $(HelixPreCommands);export DOTNET_ROOT=%24(python3 -c "import os; print(os.path.realpath('$DOTNET_ROOT'))") From a7974dd24fc13cb2c6b8db6f7bc3368e2823177e Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Tue, 17 Feb 2026 17:14:53 -0500 Subject: [PATCH 30/48] add diagnostics-pr-build-results skill Copilot CLI skill that looks up CI build results for a PR: - Finds ADO builds via GitHub PR status or ADO API - Extracts Helix job IDs from ADO build logs - Queries Helix API for per-work-item test results - Includes reference tables for test suites and build configs --- .../diagnostics-pr-build-results/SKILL.md | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 .github/skills/diagnostics-pr-build-results/SKILL.md diff --git a/.github/skills/diagnostics-pr-build-results/SKILL.md b/.github/skills/diagnostics-pr-build-results/SKILL.md new file mode 100644 index 0000000000..a4b8d2df93 --- /dev/null +++ b/.github/skills/diagnostics-pr-build-results/SKILL.md @@ -0,0 +1,163 @@ +--- +name: diagnostics-pr-build-results +description: Look up CI build results for a pull request to the diagnostics repository. Use this when asked to check build status, investigate CI failures, or get test results for a PR number. Covers ADO pipeline results and Helix test work items. +--- + +# Diagnostics PR Build Results Lookup + +Use this skill to find and analyze CI build results for pull requests in the dotnet/diagnostics repository. + +## Pipeline Details + +- **ADO Organization**: `dnceng-public` +- **ADO Project**: `public` +- **Pipeline Definition ID**: `25` (diagnostics-public-ci) +- **Pipeline URL**: https://dev.azure.com/dnceng-public/public/_build?definitionId=25 +- **Helix API**: https://helix.dot.net/api + +## Step 1: Find the ADO Build for a PR + +### Option A: From GitHub (preferred) + +Use the GitHub MCP server to get check runs for the PR: + +1. Use `github-mcp-server-pull_request_read` with `method: "get_status"` on `owner: "dotnet"`, `repo: "diagnostics"`, `pullNumber: ` to get the commit status and check runs. +2. Look for the check run from Azure Pipelines — it will have a `target_url` pointing to `dev.azure.com/dnceng-public/public/_build/results?buildId=`. +3. Extract the `buildId` from the URL. + +### Option B: From ADO directly + +Query ADO for builds triggered by the PR branch: + +``` +GET https://dev.azure.com/dnceng-public/public/_apis/build/builds?definitions=25&branchName=refs/pull//merge&$top=5&api-version=7.0 +``` + +Use the ADO PAT for authentication (Basic auth with `:PAT` base64-encoded). + +## Step 2: Get Build Results from ADO + +Once you have the `buildId`: + +1. **Get the build timeline** to see all jobs and their status: + ``` + GET https://dev.azure.com/dnceng-public/public/_apis/build/builds//timeline?api-version=7.0 + ``` + +2. **Find "Send Tests to Helix" tasks** in the timeline records: + - Filter for records where `name` contains "Send Tests to Helix" + - Check `result` (succeeded/failed) and `state` (completed) + - Each has a parent record chain: Stage > Phase > Job > Task + +3. **Get Helix Job IDs** from the task logs: + - Get the log URL from `record.log.url` + - Fetch the log content and search for `Sent Helix Job.*jobs/([a-f0-9-]+)` to extract Helix job IDs + +4. **Map jobs to build configurations** by traversing the parent chain in the timeline: + - Task → Job → Phase (has config name like `MacOS_arm64_Debug`) → Stage + +## Step 3: Query Helix for Test Results + +With the Helix job ID and access token: + +1. **List work items**: + ``` + GET https://helix.dot.net/api/jobs//workitems?api-version=2019-06-17&access_token= + ``` + +2. **Get work item details** (for failed items): + ``` + GET https://helix.dot.net/api/jobs//workitems/?api-version=2019-06-17&access_token= + ``` + Returns `State` (Failed/Passed), `ExitCode`, `ConsoleOutputUri`, `Files`. + +3. **Get console log** for a failed work item: + ``` + GET &access_token= + ``` + Search for `FAIL`, `Error Message:`, `Assert`, `Exception` lines. + +## Step 4: Summarize Results + +Present results in a table format grouped by platform: + +``` +| Platform | Config | Test Suite | Result | Details | +|-------------------|---------|-------------------|--------|-------------------| +| Linux_x64 | Debug | EventPipe | PASS | | +| Linux_x64 | Debug | SOS.UnitTests | FAIL | LLDB 14 broken | +``` + +## Authentication + +### ADO PAT +Use Basic authentication with the PAT. The user should provide the PAT, or it may be in the session context. +```powershell +$b64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) +$hdrs = @{ Authorization = "Basic $b64" } +Invoke-RestMethod -Uri $url -Headers $hdrs +``` + +### Helix Access Token +Append `&access_token=` to Helix API URLs. The user should provide the token, or it may be in the session context. + +## Common Test Suites + +These are the Helix work items sent by the diagnostics pipeline: + +| Work Item | Description | +|-----------|-------------| +| EventPipe.UnitTests | EventPipe functionality | +| Microsoft.Diagnostics.Monitoring.UnitTests | Monitoring library | +| Microsoft.FileFormats.UnitTests | File format parsing | +| Microsoft.SymbolStore.UnitTests | Symbol store | +| DotnetCounters.UnitTests | dotnet-counters tool | +| DotnetTrace.UnitTests | dotnet-trace tool | +| Microsoft.Diagnostics.NETCore.Client.UnitTests | Diagnostics client library | +| Microsoft.Diagnostics.Monitoring.EventPipe.UnitTests | EventPipe monitoring | +| SOS.UnitTests | SOS debugger extension (uses LLDB/cdb) | +| DbgShim.UnitTests | Debug shim (native dependencies) | + +## Build Configurations + +The pipeline runs these configurations (defined in `diagnostics.yml`): + +| OS | Architecture | Config | Helix Queue | +|----|-------------|--------|-------------| +| Windows_NT | x64 | Debug/Release | Windows.Amd64.Server2022.Open | +| Windows_NT | x86 | Release | Windows.Amd64.Server2022.Open | +| linux | x64 | Debug/Release | Ubuntu.2204.Amd64.Open | +| linux (musl) | x64 | Debug/Release | Ubuntu.2204.Amd64.Open | +| osx | x64 | Debug/Release | OSX.15.Amd64.Open | +| osx | arm64 | Debug/Release | OSX.15.Arm64.Open | + +## Quick Reference Script + +Here's a PowerShell script to quickly get all Helix results for a build: + +```powershell +$pat = "" +$helixToken = "" +$buildId = "" + +$b64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) +$hdrs = @{ Authorization = "Basic $b64" } + +# Get timeline +$timeline = Invoke-RestMethod -Uri "https://dev.azure.com/dnceng-public/public/_apis/build/builds/$buildId/timeline?api-version=7.0" -Headers $hdrs + +# Find Helix tasks and extract job IDs +$helixTasks = $timeline.records | Where-Object { $_.name -like "*Send Tests to Helix*" -and $_.state -eq 'completed' } +foreach ($ht in $helixTasks) { + $parent = $timeline.records | Where-Object { $_.id -eq $ht.parentId } + $grandparent = $timeline.records | Where-Object { $_.id -eq $parent.parentId } + $logContent = Invoke-RestMethod -Uri $ht.log.url -Headers $hdrs + if ($logContent -match 'jobs/([a-f0-9-]+)') { + $jobId = $Matches[1] + Write-Host "$($grandparent.name): $($ht.result) | jobId=$jobId" + # Get work items + $items = Invoke-RestMethod "https://helix.dot.net/api/jobs/$jobId/workitems?api-version=2019-06-17&access_token=$helixToken" + # ... process items + } +} +``` From 6cd02803844deacfd8a533ced3b48020a16240eb Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 09:40:54 -0500 Subject: [PATCH 31/48] try fix lldb on macos --- eng/helix.proj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/eng/helix.proj b/eng/helix.proj index 3e7042cd93..9305661c88 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -83,7 +83,14 @@ - + + + + + From eb9d9ea869be3157b0d870a2a50d40f6b69ebe99 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 10:19:32 -0500 Subject: [PATCH 32/48] install lldb-16 on Linux Helix and re-sign LLDB on macOS --- eng/helix.proj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eng/helix.proj b/eng/helix.proj index 9305661c88..8078be8b53 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -103,6 +103,9 @@ + + From cb0f185183008a899b4172a995949d713652d1f0 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 10:38:54 -0500 Subject: [PATCH 33/48] fix LLDB rpath: use dirname to get Contents/SharedFrameworks --- eng/helix.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/helix.proj b/eng/helix.proj index 8078be8b53..5835f260af 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -88,7 +88,7 @@ strips the Apple signature, allowing SOS managed commands to initialize the .NET runtime. See documentation/FAQ.md for the same workaround. --> - + From 822c583a6005a9d1cb744340c5ac7f0a259b7215 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 11:44:32 -0500 Subject: [PATCH 34/48] fix: add dpkg lock timeout for LLDB 16 install on Linux Helix apt-get was failing with 'Could not get lock /var/lib/dpkg/lock-frontend' because another process held it. Add -o DPkg::Lock::Timeout=120 to both apt-get update and install to wait for the lock instead of failing. --- eng/helix.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/helix.proj b/eng/helix.proj index 5835f260af..31c517392b 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -105,7 +105,7 @@ - + From 0c44a20376fd39756a30d6d4913b99edf70bf2ff Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 13:42:04 -0500 Subject: [PATCH 35/48] fix: unset PYTHONPATH and ensure /usr/bin/python for LLDBPluginTests SOS.LLDBPluginTests uses PYTHONPATH as the Python binary path, but Helix sets PYTHONPATH to a colon-delimited import path string. Unset it so the test falls back to /usr/bin/python, and create a symlink if needed. --- eng/helix.proj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/eng/helix.proj b/eng/helix.proj index 31c517392b..0304addfd0 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -109,6 +109,11 @@ + + + From 90285c452724080feaeab5beb0f8025d823d6d06 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:48:17 -0500 Subject: [PATCH 36/48] fix: include musl suffix in Helix TestRunNamePrefix Thread osSuffix parameter from diagnostics.yml through build.yml and send-to-helix.yml to helix.proj so that linux-musl runs display as 'linux-musl x64 Debug' instead of 'linux x64 Debug'. --- eng/helix.proj | 2 +- eng/pipelines/build.yml | 1 + eng/pipelines/send-to-helix.yml | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/eng/helix.proj b/eng/helix.proj index 0304addfd0..ee3407ac56 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -33,7 +33,7 @@ test/$(Configuration)/$(TargetArchitecture)/ $(BUILD_BUILDNUMBER) 0.0.0.0 - $(TargetOS) $(TargetArchitecture) $(Configuration) @ + $(TargetOS)$(OSSuffix) $(TargetArchitecture) $(Configuration) @ $(ArtifactsDir) diff --git a/eng/pipelines/build.yml b/eng/pipelines/build.yml index 922bedbcaa..9028093d69 100644 --- a/eng/pipelines/build.yml +++ b/eng/pipelines/build.yml @@ -184,6 +184,7 @@ jobs: configuration: ${{ config.configuration }} architecture: ${{ config.architecture }} osGroup: ${{ parameters.osGroup }} + osSuffix: ${{ parameters.osSuffix }} helixQueues: ${{ parameters.helixQueues }} isOfficialBuild: ${{ parameters.isOfficialBuild }} diff --git a/eng/pipelines/send-to-helix.yml b/eng/pipelines/send-to-helix.yml index d7172ade5a..ce97117898 100644 --- a/eng/pipelines/send-to-helix.yml +++ b/eng/pipelines/send-to-helix.yml @@ -27,6 +27,11 @@ parameters: - Linux - MacOS + # OS suffix (e.g. -musl for Alpine Linux) +- name: osSuffix + type: string + default: '' + # Helix queue to target - name: helixQueues type: string @@ -64,6 +69,7 @@ steps: /p:Configuration=${{ parameters.configuration }} /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=linux + /p:OSSuffix=${{ parameters.osSuffix }} /p:HelixTargetQueues=${{ parameters.helixQueues }} /p:HelixSource=official/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ @@ -117,6 +123,7 @@ steps: /p:Configuration=${{ parameters.configuration }} /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=linux + /p:OSSuffix=${{ parameters.osSuffix }} /p:HelixTargetQueues=${{ parameters.helixQueues }} /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ From 98aa801dddcc708d85c46f4445d09776bb43d5ce Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 14:53:21 -0500 Subject: [PATCH 37/48] Use Alpine container queues for linux-musl Helix tests Switch musl Helix queues from Ubuntu.2204 (glibc) to Alpine 3.23 containers so musl-linked native binaries (libdbgshim.so, libsosplugin.so) can load correctly. Split Linux pre-commands: - Non-musl: apt-get based LLDB 16 install (Ubuntu) - Musl: apk based LLDB/Python install (Alpine) --- eng/helix.proj | 18 ++++++++++++++---- eng/pipelines/global-variables.yml | 8 ++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index ee3407ac56..a91fa0392e 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -96,16 +96,13 @@ - + - - @@ -113,9 +110,22 @@ SOS.LLDBPluginTests misuses it as the path to the Python binary. Also ensure /usr/bin/python exists since the test falls back to it. --> + + + + + + + + + + + + @(HelixPreCommand) diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index b1cc3b96c3..30c83a0b46 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -72,9 +72,9 @@ variables: - name: HelixQueuesLinux_arm64 value: Ubuntu.2204.ArmArch.Open - name: HelixQueuesLinux_musl_x64 - value: Ubuntu.2204.Amd64.Open + value: (Alpine.323.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-amd64 - name: HelixQueuesLinux_musl_arm64 - value: Ubuntu.2204.ArmArch.Open + value: (Alpine.323.ArmArch.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-arm64v8 - name: HelixQueuesMacOS_x64 value: OSX.15.Amd64.Open - name: HelixQueuesMacOS_arm64 @@ -93,9 +93,9 @@ variables: - name: HelixQueuesLinux_arm64 value: Ubuntu.2204.ArmArch - name: HelixQueuesLinux_musl_x64 - value: Ubuntu.2204.Amd64 + value: (Alpine.323.Amd64)Ubuntu.2204.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-amd64 - name: HelixQueuesLinux_musl_arm64 - value: Ubuntu.2204.ArmArch + value: (Alpine.323.ArmArch)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-arm64v8 - name: HelixQueuesMacOS_x64 value: OSX.15.Amd64 - name: HelixQueuesMacOS_arm64 From 6e187e9f91fd9b290c07a093f741b8a389e44f9c Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:28:38 -0500 Subject: [PATCH 38/48] Quote HelixTargetQueues for container queue syntax Alpine container queue names contain () and @ characters that bash interprets as subshell/special chars. Quote the /p:HelixTargetQueues parameter in all send-to-helix.yml steps to prevent shell errors. --- eng/pipelines/send-to-helix.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/pipelines/send-to-helix.yml b/eng/pipelines/send-to-helix.yml index ce97117898..448a2b9395 100644 --- a/eng/pipelines/send-to-helix.yml +++ b/eng/pipelines/send-to-helix.yml @@ -52,7 +52,7 @@ steps: /p:Configuration=${{ parameters.configuration }} /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=Windows_NT - /p:HelixTargetQueues=${{ parameters.helixQueues }} + "/p:HelixTargetQueues=${{ parameters.helixQueues }}" /p:HelixSource=official/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ /p:HelixAccessToken=$(HelixApiAccessToken) @@ -70,7 +70,7 @@ steps: /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=linux /p:OSSuffix=${{ parameters.osSuffix }} - /p:HelixTargetQueues=${{ parameters.helixQueues }} + "/p:HelixTargetQueues=${{ parameters.helixQueues }}" /p:HelixSource=official/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ /p:HelixAccessToken=$(HelixApiAccessToken) @@ -87,7 +87,7 @@ steps: /p:Configuration=${{ parameters.configuration }} /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=osx - /p:HelixTargetQueues=${{ parameters.helixQueues }} + "/p:HelixTargetQueues=${{ parameters.helixQueues }}" /p:HelixSource=official/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ /p:HelixAccessToken=$(HelixApiAccessToken) @@ -106,7 +106,7 @@ steps: /p:Configuration=${{ parameters.configuration }} /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=Windows_NT - /p:HelixTargetQueues=${{ parameters.helixQueues }} + "/p:HelixTargetQueues=${{ parameters.helixQueues }}" /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ /p:Creator=$(Build.RequestedFor) @@ -124,7 +124,7 @@ steps: /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=linux /p:OSSuffix=${{ parameters.osSuffix }} - /p:HelixTargetQueues=${{ parameters.helixQueues }} + "/p:HelixTargetQueues=${{ parameters.helixQueues }}" /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ /p:Creator=$(Build.RequestedFor) @@ -141,7 +141,7 @@ steps: /p:Configuration=${{ parameters.configuration }} /p:TargetArchitecture=${{ parameters.architecture }} /p:TargetOS=osx - /p:HelixTargetQueues=${{ parameters.helixQueues }} + "/p:HelixTargetQueues=${{ parameters.helixQueues }}" /p:HelixSource=pr/diagnostics/$(Build.SourceBranch) /p:HelixType=test/${{ parameters.configuration }}/${{ parameters.architecture }}/ /p:Creator=$(Build.RequestedFor) From 3b5419f080be6810f92723c9f603fe792ec00f04 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Wed, 18 Feb 2026 16:54:16 -0500 Subject: [PATCH 39/48] Quote Alpine container queue values in YAML The @ character is reserved in YAML and must be quoted in plain scalars. Add single quotes around the container queue values to prevent YAML parsing failures. --- eng/pipelines/global-variables.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/pipelines/global-variables.yml b/eng/pipelines/global-variables.yml index 30c83a0b46..0818636278 100644 --- a/eng/pipelines/global-variables.yml +++ b/eng/pipelines/global-variables.yml @@ -72,9 +72,9 @@ variables: - name: HelixQueuesLinux_arm64 value: Ubuntu.2204.ArmArch.Open - name: HelixQueuesLinux_musl_x64 - value: (Alpine.323.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-amd64 + value: '(Alpine.323.Amd64.Open)Ubuntu.2204.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-amd64' - name: HelixQueuesLinux_musl_arm64 - value: (Alpine.323.ArmArch.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-arm64v8 + value: '(Alpine.323.ArmArch.Open)Ubuntu.2204.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-arm64v8' - name: HelixQueuesMacOS_x64 value: OSX.15.Amd64.Open - name: HelixQueuesMacOS_arm64 @@ -93,9 +93,9 @@ variables: - name: HelixQueuesLinux_arm64 value: Ubuntu.2204.ArmArch - name: HelixQueuesLinux_musl_x64 - value: (Alpine.323.Amd64)Ubuntu.2204.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-amd64 + value: '(Alpine.323.Amd64)Ubuntu.2204.Amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-amd64' - name: HelixQueuesLinux_musl_arm64 - value: (Alpine.323.ArmArch)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-arm64v8 + value: '(Alpine.323.ArmArch)Ubuntu.2204.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.23-helix-arm64v8' - name: HelixQueuesMacOS_x64 value: OSX.15.Amd64 - name: HelixQueuesMacOS_arm64 From 7fb1fa34cfb47c91047bda71718f32784f0996ad Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Thu, 19 Feb 2026 11:47:03 -0500 Subject: [PATCH 40/48] Fix Linux reporter crash and musl read-only filesystem 1. Remove 'unset PYTHONPATH' from common Linux pre-commands. This was breaking the Helix result reporter (ModuleNotFoundError: No module named 'helix'), causing ALL Linux x64 tests to be marked as failed even though the tests themselves pass. 2. Fix musl container read-only filesystem: correlation payload is mounted read-only in Docker containers, so cp into dotnet-cli/ fails. Create a writable DOTNET_ROOT overlay using symlinks and copy Versions.txt there instead. 3. Move Versions.txt cp into platform-specific sections since the approach differs between Ubuntu (direct cp) and Alpine (overlay). --- eng/helix.proj | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index a91fa0392e..95f4a9f779 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -102,26 +102,28 @@ - - - + - + + + + + + From 1f64ad546b2c182b3c77182baf3dd8afb578539d Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:02:08 -0500 Subject: [PATCH 41/48] Fix musl DOTNET_ROOT override and symlink glob Two issues fixed: 1. DOTNET_ROOT/PATH overrides were being clobbered by Helix SDK's AddDotNetSdk target which runs after our pre-commands. Move the overrides to a FixMuslDotNetRoot Target (AfterTargets=AddDotNetSdk) so they take effect after the SDK sets its values. 2. The * glob in 'ln -sf .../dotnet-cli/*' was treated as an MSBuild file wildcard, causing the item to silently produce no output. Escape as %2A so MSBuild passes it through as a literal *. Also use a for loop with %3B-escaped semicolons for proper bash syntax. --- eng/helix.proj | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index 95f4a9f779..4be6964ee7 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -117,13 +117,12 @@ + so create a writable DOTNET_ROOT overlay using symlinks and copy Versions.txt there. + The DOTNET_ROOT/PATH overrides happen in FixMuslDotNetRoot target (after AddDotNetSdk). --> - + - - @@ -140,6 +139,16 @@ $(HelixPreCommands);export DOTNET_ROOT=%24(python3 -c "import os; print(os.path.realpath('$DOTNET_ROOT'))") + + + + + $(HelixPreCommands);export DOTNET_ROOT=/tmp/dotnet-writable;export PATH=/tmp/dotnet-writable:$PATH + + From f26143ff20cdf89a6f35ca2ce10994e6b84aae9a Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Thu, 19 Feb 2026 14:09:20 -0500 Subject: [PATCH 42/48] try fix --- eng/helix.proj | 21 +------------------ .../Unix/Debugger.Tests.Config.txt | 2 +- .../Windows/Debugger.Tests.Config.txt | 2 +- .../Unix/Debugger.Tests.Config.txt | 2 +- .../Windows/Debugger.Tests.Config.txt | 2 +- .../Unix/Debugger.Tests.Config.txt | 2 +- .../Windows/Debugger.Tests.Config.txt | 2 +- 7 files changed, 7 insertions(+), 26 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index 4be6964ee7..eca707e955 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -59,7 +59,6 @@ <_PathSep Condition="'$(TargetOS)' != 'Windows_NT'">/ <_DotNetCliDir>$(_CorrelationPayload)$(_PathSep)dotnet-cli <_ArtifactsDir>$(_CorrelationPayload)$(_PathSep)artifacts$(_PathSep) - <_VersionsFile>$(_ArtifactsDir)dotnet-test$(_PathSep)Debugger.Tests.Versions.txt @@ -69,7 +68,6 @@ - @@ -82,7 +80,6 @@ - - - + - - - @@ -140,16 +131,6 @@ - - - - $(HelixPreCommands);export DOTNET_ROOT=/tmp/dotnet-writable;export PATH=/tmp/dotnet-writable:$PATH - - - <_VersionsStagingDir>$(ArtifactsDir)tmp\helix\dotnet-test\ diff --git a/src/tests/CommonTestRunner/ConfigFiles/Unix/Debugger.Tests.Config.txt b/src/tests/CommonTestRunner/ConfigFiles/Unix/Debugger.Tests.Config.txt index b102146da0..e2f22b01b9 100644 --- a/src/tests/CommonTestRunner/ConfigFiles/Unix/Debugger.Tests.Config.txt +++ b/src/tests/CommonTestRunner/ConfigFiles/Unix/Debugger.Tests.Config.txt @@ -1,7 +1,7 @@ $(ArtifactsDir)/dotnet-test - + $(ArtifactsDir)/bin/$(OS).$(TargetArchitecture).$(TargetConfiguration) $(ArtifactsDir)/TestResults/$(TargetConfiguration)/common.unittests_$(Timestamp) diff --git a/src/tests/CommonTestRunner/ConfigFiles/Windows/Debugger.Tests.Config.txt b/src/tests/CommonTestRunner/ConfigFiles/Windows/Debugger.Tests.Config.txt index 2e49e7dc21..f651aa0010 100644 --- a/src/tests/CommonTestRunner/ConfigFiles/Windows/Debugger.Tests.Config.txt +++ b/src/tests/CommonTestRunner/ConfigFiles/Windows/Debugger.Tests.Config.txt @@ -1,7 +1,7 @@ $(ArtifactsDir)\dotnet-test - + $(ArtifactsDir)\bin\Windows_NT.$(TargetArchitecture).$(TargetConfiguration) $(ArtifactsDir)\TestResults\$(TargetConfiguration)\common.unittests_$(Timestamp) diff --git a/src/tests/DbgShim.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt b/src/tests/DbgShim.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt index 0100eff6a7..3e39f6a4c5 100644 --- a/src/tests/DbgShim.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt +++ b/src/tests/DbgShim.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt @@ -1,7 +1,7 @@ $(ArtifactsDir)/dotnet-test - + $(ArtifactsDir)/bin/$(OS).$(TargetArchitecture).$(TargetConfiguration) $(ArtifactsDir)/TestResults/$(TargetConfiguration)/dbgshim.unittests_$(Timestamp) diff --git a/src/tests/DbgShim.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt b/src/tests/DbgShim.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt index 4687626e3f..ae82bb14a2 100644 --- a/src/tests/DbgShim.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt +++ b/src/tests/DbgShim.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt @@ -1,7 +1,7 @@ $(ArtifactsDir)\dotnet-test - + $(ArtifactsDir)\bin\Windows_NT.$(TargetArchitecture).$(TargetConfiguration) $(ArtifactsDir)\TestResults\$(TargetConfiguration)\dbgshim.unittests_$(Timestamp) diff --git a/src/tests/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt b/src/tests/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt index 2d0c1d3e75..73f496669a 100644 --- a/src/tests/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt +++ b/src/tests/SOS.UnitTests/ConfigFiles/Unix/Debugger.Tests.Config.txt @@ -10,7 +10,7 @@ $(ArtifactsDir)/dotnet-test - + ProjectK $(ArtifactsDir)/bin/SOS.UnitTests/Scripts diff --git a/src/tests/SOS.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt b/src/tests/SOS.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt index c99d4f2daf..efe29c2de1 100644 --- a/src/tests/SOS.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt +++ b/src/tests/SOS.UnitTests/ConfigFiles/Windows/Debugger.Tests.Config.txt @@ -10,7 +10,7 @@ $(ArtifactsDir)\dotnet-test - + $(ArtifactsDir)\bin\SOS.UnitTests\Scripts $(ArtifactsDir)\bin\Windows_NT.$(TargetArchitecture).$(TargetConfiguration) From 1bb42e63cb5e849de8cdac48f011447f0484efdb Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:26:43 -0500 Subject: [PATCH 43/48] try updating musl configuration --- eng/helix.proj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/eng/helix.proj b/eng/helix.proj index eca707e955..92ddca6559 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -112,8 +112,15 @@ - + + + + + + From 7dea34a49ab3006bc552c0b223d53929604ad69d Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Thu, 19 Feb 2026 16:33:56 -0500 Subject: [PATCH 44/48] update python lookup --- src/tests/SOS.UnitTests/SOS.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tests/SOS.UnitTests/SOS.cs b/src/tests/SOS.UnitTests/SOS.cs index 6f652276ff..3da9c380e6 100644 --- a/src/tests/SOS.UnitTests/SOS.cs +++ b/src/tests/SOS.UnitTests/SOS.cs @@ -715,16 +715,19 @@ public async Task LLDBPluginTests(TestConfiguration config) } else { - program = Environment.GetEnvironmentVariable("PYTHONPATH"); - if (program == null) + string pythonPath = Environment.GetEnvironmentVariable("PYTHONPATH"); + if (pythonPath != null) + { + // PYTHONPATH is a colon-separated search path; the first entry may be the python binary. + program = pythonPath.Split(':')[0]; + } + else { - // We should verify what python version this is. 2.7 is out of - // support for a while now, but we have old OS's. program = "/usr/bin/python"; } if (!File.Exists(program)) { - throw new ArgumentException($"{program} does not exists"); + throw new ArgumentException($"Cannot find python at {program}"); } } string artifactsDir = TestConfiguration.MakeCanonicalPath(config.AllSettings["ArtifactsDir"]); From bf18862091d30075bdb4ad805839b189efc4f5d3 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Thu, 19 Feb 2026 17:32:05 -0500 Subject: [PATCH 45/48] try fixing linux lldb --- eng/helix.proj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/helix.proj b/eng/helix.proj index 92ddca6559..87ae1e1f44 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -109,6 +109,8 @@ + + From afe36a01c71fc4228ddd3f69cba848c71af60cca Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 20 Feb 2026 10:42:11 -0500 Subject: [PATCH 46/48] change on musl to copy to writable directory --- eng/helix.proj | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index 87ae1e1f44..07ac1e7b23 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -115,13 +115,9 @@ + containers, so copy the artifacts directory to a writable location. --> - - - - + From 2184e3770e0f773c9f6729d6bf7b715d96bed854 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:19:56 -0500 Subject: [PATCH 47/48] try fix issues --- eng/helix.proj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index 07ac1e7b23..c1f28514fa 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -37,7 +37,7 @@ $(ArtifactsDir) - 00:30:00 + 01:00:00 true @@ -119,7 +119,7 @@ - + From 52d3fb6bbc4ef3cbf3428fd411430cd2783b7a39 Mon Sep 17 00:00:00 2001 From: Max Charlamb <44248479+max-charlamb@users.noreply.github.com> Date: Mon, 23 Feb 2026 11:07:19 -0500 Subject: [PATCH 48/48] increase SOS timeout --- eng/helix.proj | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/eng/helix.proj b/eng/helix.proj index c1f28514fa..06986c26c5 100644 --- a/eng/helix.proj +++ b/eng/helix.proj @@ -169,7 +169,9 @@ - + + 01:30:00 + @@ -283,7 +285,8 @@ Condition="Exists('$(TestArtifactsDir)bin\%(HelixTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework)')"> $(TestArtifactsDir)bin\%(HelixTestProject.Identity)\$(Configuration)\$(NetCoreAppMinTargetFramework) dotnet test %(HelixTestProject.Identity).dll --logger "trx;LogFileName=$(_UploadRoot)$(_PathSep)%(HelixTestProject.Identity).trx" - $(TestTimeout) + %(HelixTestProject.CustomTimeout) + $(TestTimeout)