From 65affe6eba6c937851b5cb95d1aaa858b39c3638 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Wed, 29 Oct 2025 17:30:48 -0700 Subject: [PATCH 1/8] Remove MSBuild dependencies from BuidlHost deps.json --- .../PackageDownloadAndReference.targets | 31 +++++++++++++++ ...alysis.Workspaces.MSBuild.BuildHost.csproj | 39 ++++++++++++++----- 2 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 eng/targets/PackageDownloadAndReference.targets diff --git a/eng/targets/PackageDownloadAndReference.targets b/eng/targets/PackageDownloadAndReference.targets new file mode 100644 index 0000000000000..66e108bc7ede5 --- /dev/null +++ b/eng/targets/PackageDownloadAndReference.targets @@ -0,0 +1,31 @@ + + + + + + + lib/$(TargetFramework) + false + + + + + + + + + + + diff --git a/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj b/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj index 148c9b6f4d71f..c1852a51e264c 100644 --- a/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj +++ b/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj @@ -21,23 +21,41 @@ --> AnyCPU true + + + <_MsbuildVersion>17.3.4 + + + + + + + + + + + + + - - - - - - + + + + + + @@ -64,18 +82,18 @@ - + - + - + @@ -93,4 +111,5 @@ + From 1846efec5df1f9102e6b8d86332169762fcb66d7 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Thu, 30 Oct 2025 15:56:57 -0700 Subject: [PATCH 2/8] Use `DotnetBuildFromSource` --- ...Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj b/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj index c1852a51e264c..80fb14a4ced75 100644 --- a/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj +++ b/src/Workspaces/Core/MSBuild.BuildHost/Microsoft.CodeAnalysis.Workspaces.MSBuild.BuildHost.csproj @@ -28,13 +28,13 @@ --> <_MsbuildVersion>17.3.4 - + - + From b8ea6e84d1bae2a82de16cdeb58eb10769ab7c13 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Fri, 31 Oct 2025 11:28:27 -0700 Subject: [PATCH 3/8] Update Arcade --- eng/Version.Details.xml | 14 +-- eng/common/SetupNugetSources.ps1 | 2 +- eng/common/SetupNugetSources.sh | 2 +- eng/common/core-templates/job/job.yml | 11 ++- .../core-templates/job/source-build.yml | 2 + .../job/source-index-stage1.yml | 4 +- .../core-templates/post-build/post-build.yml | 6 ++ .../core-templates/steps/generate-sbom.yml | 2 +- .../steps/get-delegation-sas.yml | 11 ++- .../core-templates/steps/source-build.yml | 1 + eng/common/cross/toolchain.cmake | 67 ++++++------- eng/common/generate-sbom-prep.ps1 | 20 ++-- eng/common/generate-sbom-prep.sh | 17 ++-- eng/common/internal/NuGet.config | 3 + eng/common/internal/Tools.csproj | 11 +-- eng/common/post-build/publish-using-darc.ps1 | 7 +- eng/common/sdk-task.ps1 | 2 +- eng/common/template-guidance.md | 2 +- eng/common/templates-official/job/job.yml | 16 +++ .../templates-official/steps/execute-sdl.yml | 86 ---------------- .../steps/get-delegation-sas.yml | 55 +---------- eng/common/templates/job/job.yml | 97 +++++++++---------- eng/common/templates/steps/execute-sdl.yml | 89 ----------------- .../templates/steps/get-delegation-sas.yml | 55 +---------- eng/common/tools.ps1 | 12 +-- eng/common/tools.sh | 6 +- global.json | 8 +- 27 files changed, 189 insertions(+), 419 deletions(-) delete mode 100644 eng/common/templates-official/steps/execute-sdl.yml delete mode 100644 eng/common/templates/steps/execute-sdl.yml diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index da819e1fe3410..4cdad2aec2784 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -122,17 +122,17 @@ - + https://github.com/dotnet/arcade - 8fe02bab989df1265eee225df2c28af6dbdccc83 + e29823691315ed6b3acff20d5bdf3b0be7628283 - + https://github.com/dotnet/arcade - 8fe02bab989df1265eee225df2c28af6dbdccc83 + e29823691315ed6b3acff20d5bdf3b0be7628283 - + https://github.com/dotnet/xliff-tasks 73f0850939d96131c28cf6ea6ee5aacb4da0083a @@ -156,9 +156,9 @@ https://github.com/dotnet/roslyn 5d10d428050c0d6afef30a072c4ae68776621877 - + https://github.com/dotnet/arcade - 8fe02bab989df1265eee225df2c28af6dbdccc83 + e29823691315ed6b3acff20d5bdf3b0be7628283 https://github.com/dotnet/roslyn-analyzers diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 2b0a5c9e6655e..5db4ad71ee2f3 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -157,7 +157,7 @@ if ($dotnet31Source -ne $null) { AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } -$dotnetVersions = @('5','6','7','8') +$dotnetVersions = @('5','6','7','8','9') foreach ($dotnetVersion in $dotnetVersions) { $feedPrefix = "dotnet" + $dotnetVersion; diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index b493479a1daf0..4604b61b0323a 100644 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -99,7 +99,7 @@ if [ "$?" == "0" ]; then PackageSources+=('dotnet3.1-internal-transport') fi -DotNetVersions=('5' '6' '7' '8') +DotNetVersions=('5' '6' '7' '8' '9') for DotNetVersion in ${DotNetVersions[@]} ; do FeedPrefix="dotnet${DotNetVersion}"; diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml index c732bee9f4a6f..8947ea3f0593d 100644 --- a/eng/common/core-templates/job/job.yml +++ b/eng/common/core-templates/job/job.yml @@ -19,6 +19,7 @@ parameters: # publishing defaults artifacts: '' enableMicrobuild: false + microbuildUseESRP: true enablePublishBuildArtifacts: false enablePublishBuildAssets: false enablePublishTestResults: false @@ -33,11 +34,6 @@ parameters: artifactPublishSteps: [] runAsPublic: false -# Sbom related params - enableSbom: true - PackageVersion: 9.0.0 - BuildDropPath: '$(Build.SourcesDirectory)/artifacts' - # 1es specific parameters is1ESPipeline: '' @@ -139,6 +135,11 @@ jobs: signType: $(_SignType) zipSources: false feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + ${{ if eq(parameters.microbuildUseESRP, true) }}: + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea + ${{ else }}: + ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca env: TeamName: $(_TeamName) MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' diff --git a/eng/common/core-templates/job/source-build.yml b/eng/common/core-templates/job/source-build.yml index c4713c8b6ede8..d47f09d58fd9a 100644 --- a/eng/common/core-templates/job/source-build.yml +++ b/eng/common/core-templates/job/source-build.yml @@ -26,6 +26,8 @@ parameters: # Specifies the build script to invoke to perform the build in the repo. The default # './build.sh' should work for typical Arcade repositories, but this is customizable for # difficult situations. + # buildArguments: '' + # Specifies additional build arguments to pass to the build script. # jobProperties: {} # A list of job properties to inject at the top level, for potential extensibility beyond # container and pool. diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml index 205fb5b3a3956..8b833332b3ee9 100644 --- a/eng/common/core-templates/job/source-index-stage1.yml +++ b/eng/common/core-templates/job/source-index-stage1.yml @@ -1,7 +1,7 @@ parameters: runAsPublic: false - sourceIndexUploadPackageVersion: 2.0.0-20240522.1 - sourceIndexProcessBinlogPackageVersion: 1.0.1-20240522.1 + sourceIndexUploadPackageVersion: 2.0.0-20250425.2 + sourceIndexProcessBinlogPackageVersion: 1.0.1-20250425.2 sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" preSteps: [] diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml index 454fd75c7aff1..a8c0bd3b9214e 100644 --- a/eng/common/core-templates/post-build/post-build.yml +++ b/eng/common/core-templates/post-build/post-build.yml @@ -44,6 +44,11 @@ parameters: displayName: Publish installers and checksums type: boolean default: true + + - name: requireDefaultChannels + displayName: Fail the build if there are no default channel(s) registrations for the current build + type: boolean + default: false - name: SDLValidationParameters type: object @@ -312,5 +317,6 @@ stages: -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} -AzdoToken '$(System.AccessToken)' -WaitPublishingFinish true + -RequireDefaultChannels ${{ parameters.requireDefaultChannels }} -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml index d938b60e1bb53..56a090094824f 100644 --- a/eng/common/core-templates/steps/generate-sbom.yml +++ b/eng/common/core-templates/steps/generate-sbom.yml @@ -38,7 +38,7 @@ steps: PackageName: ${{ parameters.packageName }} BuildDropPath: ${{ parameters.buildDropPath }} PackageVersion: ${{ parameters.packageVersion }} - ManifestDirPath: ${{ parameters.manifestDirPath }} + ManifestDirPath: ${{ parameters.manifestDirPath }}/$(ARTIFACT_NAME) ${{ if ne(parameters.IgnoreDirectories, '') }}: AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' diff --git a/eng/common/core-templates/steps/get-delegation-sas.yml b/eng/common/core-templates/steps/get-delegation-sas.yml index d2901470a7f0b..9db5617ea7dea 100644 --- a/eng/common/core-templates/steps/get-delegation-sas.yml +++ b/eng/common/core-templates/steps/get-delegation-sas.yml @@ -31,7 +31,16 @@ steps: # Calculate the expiration of the SAS token and convert to UTC $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") - $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv + # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads + # of correlation payloads. https://github.com/dotnet/dnceng/issues/3484 + $sas = "" + do { + $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to generate SAS token." + exit 1 + } + } while($sas.IndexOf('/') -ne -1) if ($LASTEXITCODE -ne 0) { Write-Error "Failed to generate SAS token." diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml index 2915d29bb7f6e..37133b55b7541 100644 --- a/eng/common/core-templates/steps/source-build.yml +++ b/eng/common/core-templates/steps/source-build.yml @@ -79,6 +79,7 @@ steps: ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ --configuration $buildConfig \ --restore --build --pack $publishArgs -bl \ + ${{ parameters.platform.buildArguments }} \ $officialBuildArgs \ $internalRuntimeDownloadArgs \ $internalRestoreArgs \ diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 9a4e285a5ae3f..9a7ecfbd42c5f 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -40,7 +40,7 @@ if(TARGET_ARCH_NAME STREQUAL "arm") set(TOOLCHAIN "arm-linux-gnueabihf") endif() if(TIZEN) - set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf/9.2.0") + set(TIZEN_TOOLCHAIN "armv7hl-tizen-linux-gnueabihf") endif() elseif(TARGET_ARCH_NAME STREQUAL "arm64") set(CMAKE_SYSTEM_PROCESSOR aarch64) @@ -49,7 +49,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "arm64") elseif(LINUX) set(TOOLCHAIN "aarch64-linux-gnu") if(TIZEN) - set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu/9.2.0") + set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu") endif() elseif(FREEBSD) set(triple "aarch64-unknown-freebsd12") @@ -58,7 +58,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "armel") set(CMAKE_SYSTEM_PROCESSOR armv7l) set(TOOLCHAIN "arm-linux-gnueabi") if(TIZEN) - set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi/9.2.0") + set(TIZEN_TOOLCHAIN "armv7l-tizen-linux-gnueabi") endif() elseif(TARGET_ARCH_NAME STREQUAL "armv6") set(CMAKE_SYSTEM_PROCESSOR armv6l) @@ -81,7 +81,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "riscv64") else() set(TOOLCHAIN "riscv64-linux-gnu") if(TIZEN) - set(TIZEN_TOOLCHAIN "riscv64-tizen-linux-gnu/13.1.0") + set(TIZEN_TOOLCHAIN "riscv64-tizen-linux-gnu") endif() endif() elseif(TARGET_ARCH_NAME STREQUAL "s390x") @@ -98,7 +98,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x64") elseif(LINUX) set(TOOLCHAIN "x86_64-linux-gnu") if(TIZEN) - set(TIZEN_TOOLCHAIN "x86_64-tizen-linux-gnu/9.2.0") + set(TIZEN_TOOLCHAIN "x86_64-tizen-linux-gnu") endif() elseif(FREEBSD) set(triple "x86_64-unknown-freebsd12") @@ -115,7 +115,7 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86") set(TOOLCHAIN "i686-linux-gnu") endif() if(TIZEN) - set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu/9.2.0") + set(TIZEN_TOOLCHAIN "i586-tizen-linux-gnu") endif() else() message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm, arm64, armel, armv6, ppc64le, riscv64, s390x, x64 and x86 are supported!") @@ -127,30 +127,25 @@ endif() # Specify include paths if(TIZEN) - if(TARGET_ARCH_NAME STREQUAL "arm") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7hl-tizen-linux-gnueabihf) - endif() - if(TARGET_ARCH_NAME STREQUAL "armel") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/armv7l-tizen-linux-gnueabi) - endif() - if(TARGET_ARCH_NAME STREQUAL "arm64") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/aarch64-tizen-linux-gnu) - endif() - if(TARGET_ARCH_NAME STREQUAL "x86") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}/include/c++/i586-tizen-linux-gnu) - endif() - if(TARGET_ARCH_NAME STREQUAL "x64") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/x86_64-tizen-linux-gnu) - endif() - if(TARGET_ARCH_NAME STREQUAL "riscv64") - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/) - include_directories(SYSTEM ${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}/include/c++/riscv64-tizen-linux-gnu) + function(find_toolchain_dir prefix) + # Dynamically find the version subdirectory + file(GLOB DIRECTORIES "${prefix}/*") + list(GET DIRECTORIES 0 FIRST_MATCH) + get_filename_component(TOOLCHAIN_VERSION ${FIRST_MATCH} NAME) + + set(TIZEN_TOOLCHAIN_PATH "${prefix}/${TOOLCHAIN_VERSION}" PARENT_SCOPE) + endfunction() + + if(TARGET_ARCH_NAME MATCHES "^(arm|armel|x86)$") + find_toolchain_dir("${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + else() + find_toolchain_dir("${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") endif() + + message(STATUS "TIZEN_TOOLCHAIN_PATH set to: ${TIZEN_TOOLCHAIN_PATH}") + + include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++) + include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++/${TIZEN_TOOLCHAIN}) endif() if(ANDROID) @@ -272,21 +267,21 @@ endif() if(TARGET_ARCH_NAME MATCHES "^(arm|armel)$") if(TIZEN) - add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib") - add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}") endif() elseif(TARGET_ARCH_NAME MATCHES "^(arm64|x64|riscv64)$") if(TIZEN) - add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib64") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64") - add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/lib64") add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64") - add_toolchain_linker_flag("-Wl,--rpath-link=${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-Wl,--rpath-link=${TIZEN_TOOLCHAIN_PATH}") endif() elseif(TARGET_ARCH_NAME STREQUAL "s390x") add_toolchain_linker_flag("--target=${TOOLCHAIN}") @@ -297,10 +292,10 @@ elseif(TARGET_ARCH_NAME STREQUAL "x86") endif() add_toolchain_linker_flag(-m32) if(TIZEN) - add_toolchain_linker_flag("-B${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-B${TIZEN_TOOLCHAIN_PATH}") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib") add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib") - add_toolchain_linker_flag("-L${CROSS_ROOTFS}/usr/lib/gcc/${TIZEN_TOOLCHAIN}") + add_toolchain_linker_flag("-L${TIZEN_TOOLCHAIN_PATH}") endif() elseif(ILLUMOS) add_toolchain_linker_flag("-L${CROSS_ROOTFS}/lib/amd64") diff --git a/eng/common/generate-sbom-prep.ps1 b/eng/common/generate-sbom-prep.ps1 index 3e5c1c74a1c50..a0c7d792a76fb 100644 --- a/eng/common/generate-sbom-prep.ps1 +++ b/eng/common/generate-sbom-prep.ps1 @@ -4,18 +4,26 @@ Param( . $PSScriptRoot\pipeline-logging-functions.ps1 +# Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly +# with their own overwriting ours. So we create it as a sub directory of the requested manifest path. +$ArtifactName = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM" +$SafeArtifactName = $ArtifactName -replace '["/:<>\\|?@*"() ]', '_' +$SbomGenerationDir = Join-Path $ManifestDirPath $SafeArtifactName + +Write-Host "Artifact name before : $ArtifactName" +Write-Host "Artifact name after : $SafeArtifactName" + Write-Host "Creating dir $ManifestDirPath" + # create directory for sbom manifest to be placed -if (!(Test-Path -path $ManifestDirPath)) +if (!(Test-Path -path $SbomGenerationDir)) { - New-Item -ItemType Directory -path $ManifestDirPath - Write-Host "Successfully created directory $ManifestDirPath" + New-Item -ItemType Directory -path $SbomGenerationDir + Write-Host "Successfully created directory $SbomGenerationDir" } else{ Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder." } Write-Host "Updating artifact name" -$artifact_name = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM" -replace '["/:<>\\|?@*"() ]', '_' -Write-Host "Artifact name $artifact_name" -Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$artifact_name" +Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$SafeArtifactName" diff --git a/eng/common/generate-sbom-prep.sh b/eng/common/generate-sbom-prep.sh index d5c76dc827b49..b8ecca72bbf50 100644 --- a/eng/common/generate-sbom-prep.sh +++ b/eng/common/generate-sbom-prep.sh @@ -14,19 +14,24 @@ done scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" . $scriptroot/pipeline-logging-functions.sh + +# replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts. +artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM" +safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}" manifest_dir=$1 -if [ ! -d "$manifest_dir" ] ; then - mkdir -p "$manifest_dir" - echo "Sbom directory created." $manifest_dir +# Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly +# with their own overwriting ours. So we create it as a sub directory of the requested manifest path. +sbom_generation_dir="$manifest_dir/$safe_artifact_name" + +if [ ! -d "$sbom_generation_dir" ] ; then + mkdir -p "$sbom_generation_dir" + echo "Sbom directory created." $sbom_generation_dir else Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder." fi -artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM" echo "Artifact name before : "$artifact_name -# replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts. -safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}" echo "Artifact name after : "$safe_artifact_name export ARTIFACT_NAME=$safe_artifact_name echo "##vso[task.setvariable variable=ARTIFACT_NAME]$safe_artifact_name" diff --git a/eng/common/internal/NuGet.config b/eng/common/internal/NuGet.config index 19d3d311b166f..f70261ed689bc 100644 --- a/eng/common/internal/NuGet.config +++ b/eng/common/internal/NuGet.config @@ -4,4 +4,7 @@ + + + diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj index e925952d56664..feaa6d20812d8 100644 --- a/eng/common/internal/Tools.csproj +++ b/eng/common/internal/Tools.csproj @@ -4,6 +4,7 @@ net472 false + false @@ -14,16 +15,6 @@ - - - - https://devdiv.pkgs.visualstudio.com/_packaging/dotnet-core-internal-tooling/nuget/v3/index.json; - - - $(RestoreSources); - https://devdiv.pkgs.visualstudio.com/_packaging/VS/nuget/v3/index.json; - - diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 index 90b58e32a87bf..a261517ef9067 100644 --- a/eng/common/post-build/publish-using-darc.ps1 +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -5,7 +5,8 @@ param( [Parameter(Mandatory=$false)][string] $MaestroApiEndPoint = 'https://maestro.dot.net', [Parameter(Mandatory=$true)][string] $WaitPublishingFinish, [Parameter(Mandatory=$false)][string] $ArtifactsPublishingAdditionalParameters, - [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters + [Parameter(Mandatory=$false)][string] $SymbolPublishingAdditionalParameters, + [Parameter(Mandatory=$false)][string] $RequireDefaultChannels ) try { @@ -33,6 +34,10 @@ try { if ("false" -eq $WaitPublishingFinish) { $optionalParams.Add("--no-wait") | Out-Null } + + if ("true" -eq $RequireDefaultChannels) { + $optionalParams.Add("--default-channels-required") | Out-Null + } & $darc add-build-to-channel ` --id $buildId ` diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index aab40de3fd9ac..4f0546dce1208 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -64,7 +64,7 @@ try { $GlobalJson.tools | Add-Member -Name "vs" -Value (ConvertFrom-Json "{ `"version`": `"16.5`" }") -MemberType NoteProperty } if( -not ($GlobalJson.tools.PSObject.Properties.Name -match "xcopy-msbuild" )) { - $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.10.0-pre.4.0" -MemberType NoteProperty + $GlobalJson.tools | Add-Member -Name "xcopy-msbuild" -Value "17.12.0" -MemberType NoteProperty } if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") { $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md index 5ef6c30ba9246..98bbc1ded0ba8 100644 --- a/eng/common/template-guidance.md +++ b/eng/common/template-guidance.md @@ -57,7 +57,7 @@ extends: Note: Multiple outputs are ONLY applicable to 1ES PT publishing (only usable when referencing `templates-official`). -# Development notes +## Development notes **Folder / file structure** diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 0c2928d5c799e..817555505aa60 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -1,8 +1,24 @@ +parameters: +# Sbom related params + enableSbom: true + runAsPublic: false + PackageVersion: 9.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + jobs: - template: /eng/common/core-templates/job/job.yml parameters: is1ESPipeline: true + componentGovernanceSteps: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - template: /eng/common/templates/steps/generate-sbom.yml + parameters: + PackageVersion: ${{ parameters.packageVersion }} + BuildDropPath: ${{ parameters.buildDropPath }} + ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom + publishArtifacts: false + # publish artifacts # for 1ES managed templates, use the templateContext.output to handle multiple outputs. templateContext: diff --git a/eng/common/templates-official/steps/execute-sdl.yml b/eng/common/templates-official/steps/execute-sdl.yml deleted file mode 100644 index 301d5c591ebd1..0000000000000 --- a/eng/common/templates-official/steps/execute-sdl.yml +++ /dev/null @@ -1,86 +0,0 @@ -parameters: - overrideGuardianVersion: '' - executeAllSdlToolsScript: '' - overrideParameters: '' - additionalParameters: '' - publishGuardianDirectoryToPipeline: false - sdlContinueOnError: false - condition: '' - -steps: -- task: NuGetAuthenticate@1 - -- task: NuGetToolInstaller@1 - displayName: 'Install NuGet.exe' - -- ${{ if ne(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian (Overridden) - -- ${{ if eq(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian - -- ${{ if ne(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} - displayName: Execute SDL (Overridden) - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if eq(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} - -GuardianCliLocation $(GuardianCliLocation) - -NugetPackageDirectory $(Build.SourcesDirectory)\.packages - -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) - ${{ parameters.additionalParameters }} - displayName: Execute SDL - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - -- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: - # We want to publish the Guardian results and configuration for easy diagnosis. However, the - # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default - # tooling files. Some of these files are large and aren't useful during an investigation, so - # exclude them by simply deleting them before publishing. (As of writing, there is no documented - # way to selectively exclude a dir from the pipeline artifact publish task.) - - task: DeleteFiles@1 - displayName: Delete Guardian dependencies to avoid uploading - inputs: - SourceFolder: $(Agent.BuildDirectory)/.gdn - Contents: | - c - i - condition: succeededOrFailed() - - - publish: $(Agent.BuildDirectory)/.gdn - artifact: GuardianConfiguration - displayName: Publish GuardianConfiguration - condition: succeededOrFailed() - - # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration - # with the "SARIF SAST Scans Tab" Azure DevOps extension - - task: CopyFiles@2 - displayName: Copy SARIF files - inputs: - flattenFolders: true - sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ - contents: '**/*.sarif' - targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs - condition: succeededOrFailed() - - # Use PublishBuildArtifacts because the SARIF extension only checks this case - # see microsoft/sarif-azuredevops-extension#4 - - task: PublishBuildArtifacts@1 - displayName: Publish SARIF files to CodeAnalysisLogs container - inputs: - pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs - artifactName: CodeAnalysisLogs - condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates-official/steps/get-delegation-sas.yml b/eng/common/templates-official/steps/get-delegation-sas.yml index 6e368af1ce310..c5a9c1f8275c5 100644 --- a/eng/common/templates-official/steps/get-delegation-sas.yml +++ b/eng/common/templates-official/steps/get-delegation-sas.yml @@ -1,52 +1,7 @@ -parameters: -- name: federatedServiceConnection - type: string -- name: outputVariableName - type: string -- name: expiryInHours - type: number - default: 1 -- name: base64Encode - type: boolean - default: false -- name: storageAccount - type: string -- name: container - type: string -- name: permissions - type: string - default: 'rl' - steps: -- task: AzureCLI@2 - displayName: 'Generate delegation SAS Token for ${{ parameters.storageAccount }}/${{ parameters.container }}' - inputs: - azureSubscription: ${{ parameters.federatedServiceConnection }} - scriptType: 'pscore' - scriptLocation: 'inlineScript' - inlineScript: | - # Calculate the expiration of the SAS token and convert to UTC - $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") - - # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads - # of correlation payloads. https://github.com/dotnet/dnceng/issues/3484 - $sas = "" - do { - $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SAS token." - exit 1 - } - } while($sas.IndexOf('/') -ne -1) - - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SAS token." - exit 1 - } - - if ('${{ parameters.base64Encode }}' -eq 'true') { - $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas)) - } +- template: /eng/common/core-templates/steps/get-delegation-sas.yml + parameters: + is1ESPipeline: true - Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value" - Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$sas" \ No newline at end of file + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index 8da477dd69f06..d1aeb92fcea51 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -4,6 +4,7 @@ parameters: componentGovernanceIgnoreDirectories: '' # Sbom related params enableSbom: true + runAsPublic: false PackageVersion: 9.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' @@ -19,71 +20,63 @@ jobs: steps: - ${{ each step in parameters.steps }}: - ${{ step }} - + componentGovernanceSteps: - - template: /eng/common/templates/steps/component-governance.yml - parameters: - ${{ if eq(parameters.disableComponentGovernance, '') }}: - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: - disableComponentGovernance: false - ${{ else }}: - disableComponentGovernance: true + - template: /eng/common/templates/steps/component-governance.yml + parameters: + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false ${{ else }}: - disableComponentGovernance: ${{ parameters.disableComponentGovernance }} - componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - - - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: - - template: /eng/common/templates/steps/generate-sbom.yml - parameters: - PackageVersion: ${{ parameters.packageVersion }} - BuildDropPath: ${{ parameters.buildDropPath }} - publishArtifacts: false - + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} artifactPublishSteps: - - ${{ if ne(parameters.artifacts.publish, '') }}: - - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - - template: /eng/common/core-templates/steps/publish-build-artifacts.yml - parameters: - is1ESPipeline: false - args: - displayName: Publish pipeline artifacts - pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts' - publishLocation: Container - artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} - continueOnError: true - condition: always() - - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml - parameters: - is1ESPipeline: false - args: - targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' - artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} - displayName: 'Publish logs' - continueOnError: true - condition: always() - sbomEnabled: false # we don't need SBOM for logs - - - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: - template: /eng/common/core-templates/steps/publish-build-artifacts.yml parameters: is1ESPipeline: false args: - displayName: Publish Logs - pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + displayName: Publish pipeline artifacts + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts' publishLocation: Container - artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} continueOnError: true condition: always() - - - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml parameters: is1ESPipeline: false args: - targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' - artifactName: 'BuildConfiguration' - displayName: 'Publish build retry configuration' + targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' continueOnError: true - sbomEnabled: false # we don't need SBOM for BuildConfiguration + condition: always() + sbomEnabled: false # we don't need SBOM for logs + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - template: /eng/common/core-templates/steps/publish-build-artifacts.yml + parameters: + is1ESPipeline: false + args: + displayName: Publish Logs + pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)' + publishLocation: Container + artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml + parameters: + is1ESPipeline: false + args: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true + sbomEnabled: false # we don't need SBOM for BuildConfiguration diff --git a/eng/common/templates/steps/execute-sdl.yml b/eng/common/templates/steps/execute-sdl.yml deleted file mode 100644 index fe0ebf8c904eb..0000000000000 --- a/eng/common/templates/steps/execute-sdl.yml +++ /dev/null @@ -1,89 +0,0 @@ -parameters: - overrideGuardianVersion: '' - executeAllSdlToolsScript: '' - overrideParameters: '' - additionalParameters: '' - publishGuardianDirectoryToPipeline: false - sdlContinueOnError: false - condition: '' - -steps: -- task: NuGetAuthenticate@1 - -- task: NuGetToolInstaller@1 - displayName: 'Install NuGet.exe' - -- ${{ if ne(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian (Overridden) - -- ${{ if eq(parameters.overrideGuardianVersion, '') }}: - - pwsh: | - Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl - . .\sdl.ps1 - $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts - Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" - displayName: Install Guardian - -- ${{ if ne(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} - displayName: Execute SDL (Overridden) - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - env: - GUARDIAN_DEFAULT_PACKAGE_SOURCE_SECRET: $(System.AccessToken) - -- ${{ if eq(parameters.overrideParameters, '') }}: - - powershell: ${{ parameters.executeAllSdlToolsScript }} - -GuardianCliLocation $(GuardianCliLocation) - -NugetPackageDirectory $(Build.SourcesDirectory)\.packages - ${{ parameters.additionalParameters }} - displayName: Execute SDL - continueOnError: ${{ parameters.sdlContinueOnError }} - condition: ${{ parameters.condition }} - env: - GUARDIAN_DEFAULT_PACKAGE_SOURCE_SECRET: $(System.AccessToken) - -- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: - # We want to publish the Guardian results and configuration for easy diagnosis. However, the - # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default - # tooling files. Some of these files are large and aren't useful during an investigation, so - # exclude them by simply deleting them before publishing. (As of writing, there is no documented - # way to selectively exclude a dir from the pipeline artifact publish task.) - - task: DeleteFiles@1 - displayName: Delete Guardian dependencies to avoid uploading - inputs: - SourceFolder: $(Agent.BuildDirectory)/.gdn - Contents: | - c - i - condition: succeededOrFailed() - - - publish: $(Agent.BuildDirectory)/.gdn - artifact: GuardianConfiguration - displayName: Publish GuardianConfiguration - condition: succeededOrFailed() - - # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration - # with the "SARIF SAST Scans Tab" Azure DevOps extension - - task: CopyFiles@2 - displayName: Copy SARIF files - inputs: - flattenFolders: true - sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ - contents: '**/*.sarif' - targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs - condition: succeededOrFailed() - - # Use PublishBuildArtifacts because the SARIF extension only checks this case - # see microsoft/sarif-azuredevops-extension#4 - - task: PublishBuildArtifacts@1 - displayName: Publish SARIF files to CodeAnalysisLogs container - inputs: - pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs - artifactName: CodeAnalysisLogs - condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates/steps/get-delegation-sas.yml b/eng/common/templates/steps/get-delegation-sas.yml index 6e368af1ce310..83760c9798e36 100644 --- a/eng/common/templates/steps/get-delegation-sas.yml +++ b/eng/common/templates/steps/get-delegation-sas.yml @@ -1,52 +1,7 @@ -parameters: -- name: federatedServiceConnection - type: string -- name: outputVariableName - type: string -- name: expiryInHours - type: number - default: 1 -- name: base64Encode - type: boolean - default: false -- name: storageAccount - type: string -- name: container - type: string -- name: permissions - type: string - default: 'rl' - steps: -- task: AzureCLI@2 - displayName: 'Generate delegation SAS Token for ${{ parameters.storageAccount }}/${{ parameters.container }}' - inputs: - azureSubscription: ${{ parameters.federatedServiceConnection }} - scriptType: 'pscore' - scriptLocation: 'inlineScript' - inlineScript: | - # Calculate the expiration of the SAS token and convert to UTC - $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") - - # Temporarily work around a helix issue where SAS tokens with / in them will cause incorrect downloads - # of correlation payloads. https://github.com/dotnet/dnceng/issues/3484 - $sas = "" - do { - $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SAS token." - exit 1 - } - } while($sas.IndexOf('/') -ne -1) - - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SAS token." - exit 1 - } - - if ('${{ parameters.base64Encode }}' -eq 'true') { - $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas)) - } +- template: /eng/common/core-templates/steps/get-delegation-sas.yml + parameters: + is1ESPipeline: false - Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value" - Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$sas" \ No newline at end of file + ${{ each parameter in parameters }}: + ${{ parameter.key }}: ${{ parameter.value }} diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 22954477a5747..9b3ad8840fdb2 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -42,7 +42,7 @@ [bool]$useInstalledDotNetCli = if (Test-Path variable:useInstalledDotNetCli) { $useInstalledDotNetCli } else { $true } # Enable repos to use a particular version of the on-line dotnet-install scripts. -# default URL: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.ps1 +# default URL: https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.ps1 [string]$dotnetInstallScriptVersion = if (Test-Path variable:dotnetInstallScriptVersion) { $dotnetInstallScriptVersion } else { 'v1' } # True to use global NuGet cache instead of restoring packages to repository-local directory. @@ -262,7 +262,7 @@ function GetDotNetInstallScript([string] $dotnetRoot) { if (!(Test-Path $installScript)) { Create-Directory $dotnetRoot $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit - $uri = "https://dotnet.microsoft.com/download/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.ps1" + $uri = "https://builds.dotnet.microsoft.com/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.ps1" Retry({ Write-Host "GET $uri" @@ -320,7 +320,7 @@ function InstallDotNet([string] $dotnetRoot, $variations += @($installParameters) $dotnetBuilds = $installParameters.Clone() - $dotnetbuilds.AzureFeed = "https://dotnetbuilds.azureedge.net/public" + $dotnetbuilds.AzureFeed = "https://ci.dot.net/public" $variations += @($dotnetBuilds) if ($runtimeSourceFeed) { @@ -383,8 +383,8 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # If the version of msbuild is going to be xcopied, # use this version. Version matches a package here: - # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.10.0-pre.4.0 - $defaultXCopyMSBuildVersion = '17.10.0-pre.4.0' + # https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-eng/NuGet/Microsoft.DotNet.Arcade.MSBuild.Xcopy/versions/17.12.0 + $defaultXCopyMSBuildVersion = '17.12.0' if (!$vsRequirements) { if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') { @@ -416,7 +416,7 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = # Locate Visual Studio installation or download x-copy msbuild. $vsInfo = LocateVisualStudio $vsRequirements - if ($vsInfo -ne $null) { + if ($vsInfo -ne $null -and $env:ForceUseXCopyMSBuild -eq $null) { # Ensure vsInstallDir has a trailing slash $vsInstallDir = Join-Path $vsInfo.installationPath "\" $vsMajorVersion = $vsInfo.installationVersion.Split('.')[0] diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 00473c9f918d4..01b09b65796c1 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -54,7 +54,7 @@ warn_as_error=${warn_as_error:-true} use_installed_dotnet_cli=${use_installed_dotnet_cli:-true} # Enable repos to use a particular version of the on-line dotnet-install scripts. -# default URL: https://dotnet.microsoft.com/download/dotnet/scripts/v1/dotnet-install.sh +# default URL: https://builds.dotnet.microsoft.com/dotnet/scripts/v1/dotnet-install.sh dotnetInstallScriptVersion=${dotnetInstallScriptVersion:-'v1'} # True to use global NuGet cache instead of restoring packages to repository-local directory. @@ -232,7 +232,7 @@ function InstallDotNet { local public_location=("${installParameters[@]}") variations+=(public_location) - local dotnetbuilds=("${installParameters[@]}" --azure-feed "https://dotnetbuilds.azureedge.net/public") + local dotnetbuilds=("${installParameters[@]}" --azure-feed "https://ci.dot.net/public") variations+=(dotnetbuilds) if [[ -n "${6:-}" ]]; then @@ -295,7 +295,7 @@ function with_retries { function GetDotNetInstallScript { local root=$1 local install_script="$root/dotnet-install.sh" - local install_script_url="https://dotnet.microsoft.com/download/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.sh" + local install_script_url="https://builds.dotnet.microsoft.com/dotnet/scripts/$dotnetInstallScriptVersion/dotnet-install.sh" if [[ ! -a "$install_script" ]]; then mkdir -p "$root" diff --git a/global.json b/global.json index 83db5cc6d99e7..60efe213df4b6 100644 --- a/global.json +++ b/global.json @@ -1,18 +1,18 @@ { "sdk": { - "version": "9.0.100-preview.5.24307.3", + "version": "9.0.109", "allowPrerelease": false, "rollForward": "patch" }, "tools": { - "dotnet": "9.0.100-preview.5.24307.3", + "dotnet": "9.0.109", "vs": { "version": "17.8.0" } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24416.2", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24416.2", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25407.2", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.25407.2", "Microsoft.Build.Traversal": "3.4.0" } } From cda8483c80d061f1f0f32538dabe51d4d5766d8a Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Fri, 31 Oct 2025 11:41:34 -0700 Subject: [PATCH 4/8] Disable EOL target framework check --- eng/targets/Settings.props | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/eng/targets/Settings.props b/eng/targets/Settings.props index 4e8a4b0c1b6b2..7b87443095846 100644 --- a/eng/targets/Settings.props +++ b/eng/targets/Settings.props @@ -16,6 +16,9 @@ $(NoWarn);NU1507 + + false + CommonExtensions Microsoft\VBCSharp\LanguageServices @@ -58,7 +61,7 @@ false true - + <_SkipUpgradeNetAnalyzersNuGetWarning>true From c62e44706f0b1a119dc232c1d8eb083bc80bf852 Mon Sep 17 00:00:00 2001 From: Joey Robichaud Date: Fri, 31 Oct 2025 12:52:56 -0700 Subject: [PATCH 5/8] Add expected diagnostic to fix MSBuildWorkspace test --- .../MSBuildTest/NewlyCreatedProjectsFromDotNetNew.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Workspaces/MSBuildTest/NewlyCreatedProjectsFromDotNetNew.cs b/src/Workspaces/MSBuildTest/NewlyCreatedProjectsFromDotNetNew.cs index 9e876add938d6..afbfb331777f5 100644 --- a/src/Workspaces/MSBuildTest/NewlyCreatedProjectsFromDotNetNew.cs +++ b/src/Workspaces/MSBuildTest/NewlyCreatedProjectsFromDotNetNew.cs @@ -71,7 +71,15 @@ public async Task ValidateCSharpTemplateProjects(string templateName) return; } - await AssertTemplateProjectLoadsCleanlyAsync(templateName, LanguageNames.CSharp); + string[] ignoredDiagniostics = templateName switch + { + // We expect the following error until it is resolved in 17.12. See https://github.com/dotnet/roslyn/issues/74511 + // error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated' to your project. + "webapiaot" => ["CS9137"], + _ => [], + }; + + await AssertTemplateProjectLoadsCleanlyAsync(templateName, LanguageNames.CSharp, ignoredDiagniostics); } [ConditionalTheory(typeof(DotNetSdkMSBuildInstalled))] From da2415cb227c61fca26bce6cfeb05e98b847a9f4 Mon Sep 17 00:00:00 2001 From: Fred Silberberg Date: Fri, 11 Apr 2025 15:26:31 -0700 Subject: [PATCH 6/8] Disable failing Test1 and Test5 lines (#78118) --- .../Test/Semantic/Semantics/BinaryOperatorsTestBaseline1.txt | 2 -- .../Test/Semantic/Semantics/BinaryOperatorsTestBaseline5.txt | 2 -- .../Test/Semantic/Semantics/BinaryOperatorsTestSource1.vb | 4 ++-- .../Test/Semantic/Semantics/BinaryOperatorsTestSource5.vb | 4 ++-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline1.txt b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline1.txt index 32720e6ace6c2..2862e8c5f007b 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline1.txt +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline1.txt @@ -1611,7 +1611,6 @@ [UI ^ SB] Double: 0.0384615384615385 [UI ^ By] Double: 1.34714286531616E+31 [UI ^ Sh] Double: 5.68957669549386E-05 -[UI ^ US] Double: 9.10668576953722E+33 [UI ^ [In]] Double: 8.41653357321576E-08 [UI ^ UI] Double: 6.15611958020716E+36 [UI ^ Lo] Double: 1.24504934515026E-10 @@ -1666,7 +1665,6 @@ [De ^ UL] Double: 5.23347633027361E+26 [De ^ De] Double: -2.5811747917132E-09 [De ^ Si] Double: 3486784401 -[De ^ [Do]] Double: -3.18663554532494E-11 [De ^ St] Double: 282429536481 [De ^ Ob] Object: -3.93411795719128E-13 [De ^ Tc] Double: 22876792454961 diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline5.txt b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline5.txt index 30a5e7d329061..0e83c186e8778 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline5.txt +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestBaseline5.txt @@ -1420,7 +1420,6 @@ [26UI ^ System.SByte.MinValue] Double: 7.64559800600316E-182 [26UI ^ System.Byte.MaxValue] Double: Infinity [26UI ^ -3S] Double: 5.68957669549386E-05 -[26UI ^ 24US] Double: 9.10668576953722E+33 [26UI ^ -5I] Double: 8.41653357321576E-08 [26UI ^ 26UI] Double: 6.15611958020716E+36 [26UI ^ -7L] Double: 1.24504934515026E-10 @@ -1472,7 +1471,6 @@ [-9D ^ 28UL] Double: -5.23347633027361E+26 [-9D ^ -9D] Double: -2.5811747917132E-09 [-9D ^ 10.0F] Double: -3486784401 -[-9D ^ -11.0R] Double: -3.18663554532494E-11 [-9D ^ "12"] Double: -282429536481 [-9D ^ TypeCode.Double] Double: -22876792454961 [10.0F ^ False] Double: 1 diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource1.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource1.vb index 38250e17a556b..ac276a46f583d 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource1.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource1.vb @@ -1684,7 +1684,7 @@ Module Module1 PrintResult("UI ^ SB", UI ^ SB) PrintResult("UI ^ By", UI ^ By) PrintResult("UI ^ Sh", UI ^ Sh) - PrintResult("UI ^ US", UI ^ US) + ' PrintResult("UI ^ US", UI ^ US) ' https://github.com/dotnet/roslyn/issues/78117 PrintResult("UI ^ [In]", UI ^ [In]) PrintResult("UI ^ UI", UI ^ UI) PrintResult("UI ^ Lo", UI ^ Lo) @@ -1739,7 +1739,7 @@ Module Module1 PrintResult("De ^ UL", De ^ UL) PrintResult("De ^ De", De ^ De) PrintResult("De ^ Si", De ^ Si) - PrintResult("De ^ [Do]", De ^ [Do]) + ' PrintResult("De ^ [Do]", De ^ [Do]) ' https://github.com/dotnet/roslyn/issues/78117 PrintResult("De ^ St", De ^ St) PrintResult("De ^ Ob", De ^ Ob) PrintResult("De ^ Tc", De ^ Tc) diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource5.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource5.vb index 9ed4c5f230c22..d9d07c5dd4672 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource5.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/BinaryOperatorsTestSource5.vb @@ -1432,7 +1432,7 @@ Module Module1 PrintResult("26UI ^ System.SByte.MinValue", 26UI ^ System.SByte.MinValue) PrintResult("26UI ^ System.Byte.MaxValue", 26UI ^ System.Byte.MaxValue) PrintResult("26UI ^ -3S", 26UI ^ -3S) - PrintResult("26UI ^ 24US", 26UI ^ 24US) + ' PrintResult("26UI ^ 24US", 26UI ^ 24US) ' https://github.com/dotnet/roslyn/issues/78117 PrintResult("26UI ^ -5I", 26UI ^ -5I) PrintResult("26UI ^ 26UI", 26UI ^ 26UI) PrintResult("26UI ^ -7L", 26UI ^ -7L) @@ -1484,7 +1484,7 @@ Module Module1 PrintResult("-9D ^ 28UL", -9D ^ 28UL) PrintResult("-9D ^ -9D", -9D ^ -9D) PrintResult("-9D ^ 10.0F", -9D ^ 10.0F) - PrintResult("-9D ^ -11.0R", -9D ^ -11.0R) + ' PrintResult("-9D ^ -11.0R", -9D ^ -11.0R) ' https://github.com/dotnet/roslyn/issues/78117 PrintResult("-9D ^ ""12""", -9D ^ "12") PrintResult("-9D ^ TypeCode.Double", -9D ^ TypeCode.Double) PrintResult("10.0F ^ False", 10.0F ^ False) From 1450dfd1b01b9c4b0142fb660b5f99078200bf34 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Wed, 3 Jul 2024 11:52:48 -0700 Subject: [PATCH 7/8] Fix flaky streaming FAR test --- .../FindAllReferencesHandlerTests.cs | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs index 34dad5ed303cf..645f7d49852c3 100644 --- a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs @@ -84,14 +84,6 @@ void M2() var results = await RunFindAllReferencesAsync(testLspServer, testLspServer.GetLocations("caret").First(), progress); - Assert.Null(results); - - // BufferedProgress wraps individual elements in an array, so when they are nested them like this, - // with the test creating one, and the handler another, we have to unwrap. - // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual VSInternalReferenceItem - // so we have to correctly convert the JObject into the expected type. - results = progress.GetValues().SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)).ToArray(); - Assert.NotNull(results); Assert.NotEmpty(results); @@ -287,21 +279,51 @@ private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IPr PartialResultToken = progress }; - internal static async Task RunFindAllReferencesAsync(TestLspServer testLspServer, LSP.Location caret, IProgress progress = null) + internal static async Task RunFindAllReferencesAsync(TestLspServer testLspServer, LSP.Location caret, BufferedProgress? progress = null) { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); // Results are returned in a non-deterministic order, so we order them by location var orderedResults = results?.OrderBy(r => r.Location, new OrderLocations()).ToArray(); + + // If we're using progress, we need to return the results from the progress object. + if (progress != null) + { + Assert.Null(orderedResults); + // BufferedProgress wraps individual elements in an array, so when they are nested them like this, + // with the test creating one, and the handler another, we have to unwrap. + // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual VSInternalReferenceItem + // so we have to correctly convert the JObject into the expected type. + orderedResults = progress.Value.GetValues() + .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) + .OrderBy(r => r.Location, new OrderLocations()) + .ToArray(); + } + return orderedResults; } - internal static async Task RunFindAllReferencesNonVSAsync(TestLspServer testLspServer, LSP.Location caret, IProgress progress = null) + internal static async Task RunFindAllReferencesNonVSAsync(TestLspServer testLspServer, LSP.Location caret, BufferedProgress? progress = null) { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); // Results are returned in a non-deterministic order, so we order them by location var orderedResults = results.OrderBy(r => r, new OrderLocations()).ToArray(); + + // If we're using progress, we need to return the results from the progress object. + if (progress != null) + { + Assert.Null(orderedResults); + // BufferedProgress wraps individual elements in an array, so when they are nested them like this, + // with the test creating one, and the handler another, we have to unwrap. + // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual LSP.Location + // so we have to correctly convert the JObject into the expected type. + orderedResults = progress.Value.GetValues() + .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) + .OrderBy(r => r, new OrderLocations()) + .ToArray(); + } + return orderedResults; } From eda7009cd28228fb43d9ab9f2f9dace62e7e67e8 Mon Sep 17 00:00:00 2001 From: David Barbet Date: Wed, 3 Jul 2024 12:12:30 -0700 Subject: [PATCH 8/8] Cleanup a bit --- .../FindAllReferencesHandlerTests.cs | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs index 645f7d49852c3..f9422d9432c00 100644 --- a/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs +++ b/src/LanguageServer/ProtocolUnitTests/References/FindAllReferencesHandlerTests.cs @@ -283,23 +283,16 @@ private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IPr { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); - // Results are returned in a non-deterministic order, so we order them by location - var orderedResults = results?.OrderBy(r => r.Location, new OrderLocations()).ToArray(); - // If we're using progress, we need to return the results from the progress object. + // If we're using progress, return the results from that instead. if (progress != null) { - Assert.Null(orderedResults); - // BufferedProgress wraps individual elements in an array, so when they are nested them like this, - // with the test creating one, and the handler another, we have to unwrap. - // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual VSInternalReferenceItem - // so we have to correctly convert the JObject into the expected type. - orderedResults = progress.Value.GetValues() - .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) - .OrderBy(r => r.Location, new OrderLocations()) - .ToArray(); + Assert.Null(results); + results = UnwrapProgress(progress.Value).ToArray(); } + // Results are returned in a non-deterministic order, so we order them by location + var orderedResults = results?.OrderBy(r => r.Location, new OrderLocations()).ToArray(); return orderedResults; } @@ -307,26 +300,30 @@ private static LSP.ReferenceParams CreateReferenceParams(LSP.Location caret, IPr { var results = await testLspServer.ExecuteRequestAsync(LSP.Methods.TextDocumentReferencesName, CreateReferenceParams(caret, progress), CancellationToken.None); - // Results are returned in a non-deterministic order, so we order them by location - var orderedResults = results.OrderBy(r => r, new OrderLocations()).ToArray(); - // If we're using progress, we need to return the results from the progress object. + // If we're using progress, return the results from that instead. if (progress != null) { - Assert.Null(orderedResults); - // BufferedProgress wraps individual elements in an array, so when they are nested them like this, - // with the test creating one, and the handler another, we have to unwrap. - // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual LSP.Location - // so we have to correctly convert the JObject into the expected type. - orderedResults = progress.Value.GetValues() - .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) - .OrderBy(r => r, new OrderLocations()) - .ToArray(); + Assert.Null(results); + results = UnwrapProgress(progress.Value).ToArray(); } + // Results are returned in a non-deterministic order, so we order them by location + var orderedResults = results.OrderBy(r => r, new OrderLocations()).ToArray(); return orderedResults; } + private static T[] UnwrapProgress(BufferedProgress progress) + { + // BufferedProgress wraps individual elements in an array, so when they are nested them like this, + // with the test creating one, and the handler another, we have to unwrap. + // Additionally, the VS LSP protocol specifies T from IProgress as an object and not as the actual T type + // so we have to correctly convert the JObject into the expected type. + return progress.GetValues() + .SelectMany(r => (List)r).Select(r => JsonSerializer.Deserialize((JsonElement)r, ProtocolConversions.LspJsonSerializerOptions)) + .ToArray(); + } + private static void AssertValidDefinitionProperties(LSP.VSInternalReferenceItem[] referenceItems, int definitionIndex, Glyph definitionGlyph) { var definition = referenceItems[definitionIndex];