diff --git a/.vsts-dotnet.yml b/.vsts-dotnet.yml index bfe64b23ccb..fcf2a8cb234 100644 --- a/.vsts-dotnet.yml +++ b/.vsts-dotnet.yml @@ -34,7 +34,7 @@ variables: - name: SourceBranch value: '' - name: EnableReleaseOneLocBuild - value: true # Enable loc for vs17.13 + value: false # Disable loc for vs17.13 - name: Codeql.Enabled value: true - group: AzureDevOps-Artifact-Feeds-Pats diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4df1480dd3e..898f1b6b789 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -71,19 +71,19 @@ - + https://github.com/dotnet/arcade - 5da211e1c42254cb35e7ef3d5a8428fb24853169 + 5ba9ca776c1d0bb72b2791591e54cf51fc52dfee - + https://github.com/dotnet/arcade - 5da211e1c42254cb35e7ef3d5a8428fb24853169 + 5ba9ca776c1d0bb72b2791591e54cf51fc52dfee - + https://github.com/dotnet/arcade - 5da211e1c42254cb35e7ef3d5a8428fb24853169 + 5ba9ca776c1d0bb72b2791591e54cf51fc52dfee https://github.com/nuget/nuget.client @@ -98,9 +98,9 @@ 31f8433cb625e2aa74d148005003b21d5e3f67b7 - + https://github.com/dotnet/arcade - 5da211e1c42254cb35e7ef3d5a8428fb24853169 + 5ba9ca776c1d0bb72b2791591e54cf51fc52dfee diff --git a/eng/Versions.props b/eng/Versions.props index 536689cba97..209697fbc98 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -2,7 +2,7 @@ - 17.13.20 + 17.13.23 release 17.12.6 15.1.0.0 @@ -62,7 +62,7 @@ Otherwise, this version of dotnet will not be installed and the build will error out. --> $([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\global.json')), '"dotnet": "([^"]*)"').Groups.get_Item(1)) 4.2.0-1.22102.8 - 9.0.0-beta.25111.5 + 9.0.0-beta.25164.2 4.13.0-3.24607.3 6.13.0-rc.93 diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml index d938b60e1bb..56a09009482 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/generate-sbom-prep.ps1 b/eng/common/generate-sbom-prep.ps1 index 3e5c1c74a1c..a0c7d792a76 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 d5c76dc827b..b8ecca72bbf 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/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 605692d2fb7..817555505aa 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -16,6 +16,7 @@ jobs: parameters: PackageVersion: ${{ parameters.packageVersion }} BuildDropPath: ${{ parameters.buildDropPath }} + ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom publishArtifacts: false # publish artifacts diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index a46b6deb759..22b49e09d09 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" diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 1159726a10f..01b09b65796 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. @@ -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 ee7246df20f..e2e3c22ae34 100644 --- a/global.json +++ b/global.json @@ -3,13 +3,13 @@ "allowPrerelease": true }, "tools": { - "dotnet": "9.0.103", + "dotnet": "9.0.104", "vs": { "version": "17.12.0" }, "xcopy-msbuild": "17.12.0" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25111.5" + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.25164.2" } } diff --git a/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs b/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs index a5041d55fd6..179ce327667 100644 --- a/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs +++ b/src/Build.UnitTests/Evaluation/SdkResultEvaluation_Tests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Xml; using Microsoft.Build.Construction; using Microsoft.Build.Definition; using Microsoft.Build.Evaluation; @@ -137,6 +138,48 @@ public void SdkResolverCanReturnNoPaths(bool includePropertiesAndItems) _logger.WarningCount.ShouldBe(0); } + [Fact] + public void SuccessfullyEvaluatesSdkResultWithPropertiesForNullProjectRootElement() + { + Dictionary propertiesToAdd = null; + Dictionary itemsToAdd = null; + + CreateMockSdkResultPropertiesAndItems(out propertiesToAdd, out itemsToAdd); + + var projectOptions = SdkUtilities.CreateProjectOptionsWithResolver(new SdkUtilities.ConfigurableMockSdkResolver( + new Build.BackEnd.SdkResolution.SdkResult( + new SdkReference("TestPropsAndItemsFromResolverSdk", null, null), + Enumerable.Empty(), + version: null, + propertiesToAdd, + itemsToAdd, + warnings: null))); + + string projectContent = @" + + + "; + + string projectPath = Path.Combine(_testFolder, "project.proj"); + File.WriteAllText(projectPath, projectContent); + + using XmlReader xmlReader = XmlReader.Create(projectPath); + try + { + ProjectRootElement projectRootElement = ProjectRootElement.Open(projectPath, _projectCollection); + + projectOptions.ProjectCollection = _projectCollection; + + // Creating project from XmlReader results in null ProjectRootElement on Evaluation phase. + // In that case project created for SdkResult properties and items is given a unique file name {Guid}.SdkResolver.{propertiesAndItemsHash}.proj in the current directory + Project.FromXmlReader(xmlReader, projectOptions); + } + catch (Exception ex) + { + Assert.Fail("Expected no exception, but got: " + ex.ToString()); + } + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] diff --git a/src/Build/Evaluation/Evaluator.cs b/src/Build/Evaluation/Evaluator.cs index f2b0b2839c3..a1c0baca577 100644 --- a/src/Build/Evaluation/Evaluator.cs +++ b/src/Build/Evaluation/Evaluator.cs @@ -1912,8 +1912,13 @@ private ProjectRootElement CreateProjectForSdkResult(SdkResult sdkResult) propertiesAndItemsHash = hash.ToHashCode(); #endif - // Generate a unique filename for the generated project for each unique set of properties and items. - string projectPath = _projectRootElement.FullPath + ".SdkResolver." + propertiesAndItemsHash + ".proj"; + // Generate a unique filename for the generated project for each unique set of properties and items that ends like ".SdkResolver.{propertiesAndItemsHash}.proj". + // _projectRootElement.FullPath can be null. This can be in the case when Project is created from XmlReader. For that case we generate filename like "{Guid}.SdkResolver.{propertiesAndItemsHash}.proj in the current directory. + // Oterwise the project is in the same directory as _projectRootElement and has a name of the saem project and ends like ".SdkResolver.{propertiesAndItemsHash}.proj". + string projectNameEnding = $".SdkResolver.{propertiesAndItemsHash}.proj"; + string projectPath = _projectRootElement.FullPath != null ? + _projectRootElement.FullPath + projectNameEnding : + FileUtilities.NormalizePath(Guid.NewGuid() + projectNameEnding); ProjectRootElement InnerCreate(string _, ProjectRootElementCacheBase __) {