diff --git a/NuGet.config b/NuGet.config
index 2c233f9c47f..84541553c4b 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -7,13 +7,10 @@
-
-
+
-
-
diff --git a/docs/benchmarkdotnet.md b/docs/benchmarkdotnet.md
index f8c9e222849..be429f57ad7 100644
--- a/docs/benchmarkdotnet.md
+++ b/docs/benchmarkdotnet.md
@@ -289,7 +289,7 @@ M00_L00:
The `--runtimes` or just `-r` allows you to run the benchmarks for **multiple Runtimes**.
-Available options are: Mono, wasmnet70, CoreRT, net462, net47, net471, net472, netcoreapp3.1, net6.0, net7.0, net8.0, and net9.0.
+Available options are: Mono, wasmnet70, CoreRT, netcoreapp3.1, net6.0, net7.0, net8.0, and net9.0.
Example: run the benchmarks for .NET 7.0 and 8.0:
@@ -361,18 +361,6 @@ dotnet run -c Release -f net9.0 --cli "C:\Projects\performance\.dotnet\dotnet.ex
This is very useful when you want to compare different builds of .NET.
-### Private CLR Build
-
-It's possible to benchmark a private build of .NET Runtime. You just need to pass the value of `COMPLUS_Version` to BenchmarkDotNet. You can do that by either using `--clrVersion $theVersion` as an argument or `Job.ShortRun.With(new ClrRuntime(version: "$theVersion"))` in the code.
-
-So if you made a change in CLR and want to measure the difference, you can run the benchmarks with:
-
-```cmd
-dotnet run -c Release -f net48 -- --clrVersion $theVersion
-```
-
-More info can be found in [BenchmarkDotNet issue #706](https://github.com/dotnet/BenchmarkDotNet/issues/706).
-
### Private CoreRT Build
To run benchmarks with private CoreRT build you need to provide the `IlcPath`. Example:
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 6edc23c1cef..c345e47db95 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,39 +1,39 @@
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
-
+
https://github.com/dotnet/dotnet
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+ 547c640d5626b2976499cb3433abc741a63d67c5
https://github.com/dotnet/xharness
@@ -55,17 +55,17 @@
6e563dcf3cbf4853316eb4724e49ec92caeabb07
https://github.com/dotnet/maui
-
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+
+ 547c640d5626b2976499cb3433abc741a63d67c5
https://github.com/dotnet/dotnet
-
- 5bed4499b04cbbaec57ac4209ae993acca3648cc
+
+ 547c640d5626b2976499cb3433abc741a63d67c5
https://github.com/dotnet/dotnet
-
+
https://github.com/dotnet/android
- 9f89a27a70ce6828cffc2e66c967dd047b98656a
+ 6b255ec42cef9f9f757400f6edec7af239cacd58
4c9d1b112c16716c2479e054e9ad4db8b5b8c70c
diff --git a/eng/Versions.props b/eng/Versions.props
index c8cece31b71..07ade91729c 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -7,12 +7,12 @@
- 11.0.0-preview.4.26210.111
- 11.0.0-preview.4.26210.111
- 11.0.0-preview.4.26210.111
- 11.0.0-preview.4.26210.111
- 0.16.0-nightly.20260320.467
- 11.0.0-preview.4.26210.111
+ 11.0.0-preview.5.26261.101
+ 11.0.0-preview.5.26261.101
+ 11.0.0-preview.5.26261.101
+ 11.0.0-preview.5.26261.101
+ 0.16.0-nightly.20260518.1249
+ 11.0.0-preview.5.26261.101
11.0.0-prerelease.26204.1
diff --git a/eng/common/AGENTS.md b/eng/common/AGENTS.md
new file mode 100644
index 00000000000..a5ed8f72926
--- /dev/null
+++ b/eng/common/AGENTS.md
@@ -0,0 +1,5 @@
+# `eng/common`
+
+Files under `eng/common` come from [Arcade](https://github.com/dotnet/arcade).
+Edits in `eng/common` will be overwritten by automation unless the changes are made directly in the Arcade repository.
+For more information, see the [Arcade documentation](https://github.com/dotnet/arcade/tree/main/Documentation).
diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml
index 748c4f07a64..66c7988f222 100644
--- a/eng/common/core-templates/job/job.yml
+++ b/eng/common/core-templates/job/job.yml
@@ -26,12 +26,12 @@ parameters:
enablePublishBuildArtifacts: false
enablePublishBuildAssets: false
enablePublishTestResults: false
+ enablePublishing: false
enableBuildRetry: false
mergeTestResults: false
testRunTitle: ''
testResultsFormat: ''
name: ''
- componentGovernanceSteps: []
preSteps: []
artifactPublishSteps: []
runAsPublic: false
@@ -152,9 +152,6 @@ jobs:
- ${{ each step in parameters.steps }}:
- ${{ step }}
- - ${{ each step in parameters.componentGovernanceSteps }}:
- - ${{ step }}
-
- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- template: /eng/common/core-templates/steps/cleanup-microbuild.yml
parameters:
diff --git a/eng/common/core-templates/job/onelocbuild.yml b/eng/common/core-templates/job/onelocbuild.yml
index eefed3b667a..86ea9f63504 100644
--- a/eng/common/core-templates/job/onelocbuild.yml
+++ b/eng/common/core-templates/job/onelocbuild.yml
@@ -22,6 +22,7 @@ parameters:
GitHubOrg: dotnet
MirrorRepo: ''
MirrorBranch: main
+ xLocCustomPowerShellScript: ''
condition: ''
JobNameSuffix: ''
is1ESPipeline: ''
@@ -97,6 +98,8 @@ jobs:
gitHubOrganization: ${{ parameters.GitHubOrg }}
mirrorRepo: ${{ parameters.MirrorRepo }}
mirrorBranch: ${{ parameters.MirrorBranch }}
+ ${{ if ne(parameters.xLocCustomPowerShellScript, '') }}:
+ xLocCustomPowerShellScript: ${{ parameters.xLocCustomPowerShellScript }}
condition: ${{ parameters.condition }}
# Copy the locProject.json to the root of the Loc directory, then publish a pipeline artifact
diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml
index 9d7490518c4..700f7711465 100644
--- a/eng/common/core-templates/job/publish-build-assets.yml
+++ b/eng/common/core-templates/job/publish-build-assets.yml
@@ -172,17 +172,18 @@ jobs:
targetPath: '$(Build.ArtifactStagingDirectory)/MergedManifest.xml'
artifactName: AssetManifests
displayName: 'Publish Merged Manifest'
- retryCountOnTaskFailure: 10 # for any logs being locked
- sbomEnabled: false # we don't need SBOM for logs
+ retryCountOnTaskFailure: 10 # for any files being locked
+ isProduction: false # just metadata for publishing
- - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+ - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
args:
displayName: Publish ReleaseConfigs Artifact
- pathToPublish: '$(Build.StagingDirectory)/ReleaseConfigs'
- publishLocation: Container
+ targetPath: '$(Build.StagingDirectory)/ReleaseConfigs'
artifactName: ReleaseConfigs
+ retryCountOnTaskFailure: 10 # for any files being locked
+ isProduction: false # just metadata for publishing
- ${{ if or(eq(parameters.publishAssetsImmediately, 'true'), eq(parameters.isAssetlessBuild, 'true')) }}:
- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
@@ -218,4 +219,5 @@ jobs:
- template: /eng/common/core-templates/steps/publish-logs.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
+ StageLabel: 'BuildAssetRegistry'
JobLabel: 'Publish_Artifacts_Logs'
diff --git a/eng/common/core-templates/job/renovate.yml b/eng/common/core-templates/job/renovate.yml
index ab233539b5d..ff86c80b468 100644
--- a/eng/common/core-templates/job/renovate.yml
+++ b/eng/common/core-templates/job/renovate.yml
@@ -135,7 +135,7 @@ jobs:
condition: succeededOrFailed()
targetPath: $(Build.ArtifactStagingDirectory)
artifactName: $(Agent.JobName)_Logs_Attempt$(System.JobAttempt)
- sbomEnabled: false
+ isProduction: false # logs are non-production artifacts
steps:
- checkout: self
diff --git a/eng/common/core-templates/jobs/jobs.yml b/eng/common/core-templates/jobs/jobs.yml
index 01ada747665..cc8cce45278 100644
--- a/eng/common/core-templates/jobs/jobs.yml
+++ b/eng/common/core-templates/jobs/jobs.yml
@@ -43,6 +43,10 @@ parameters:
artifacts: {}
is1ESPipeline: ''
+
+ # Publishing version w/default.
+ publishingVersion: 3
+
repositoryAlias: self
officialBuildId: ''
@@ -102,6 +106,7 @@ jobs:
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
continueOnError: ${{ parameters.continueOnError }}
+ publishingVersion: ${{ parameters.publishingVersion }}
dependsOn:
- ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}:
- ${{ each job in parameters.publishBuildAssetsDependsOn }}:
diff --git a/eng/common/core-templates/post-build/common-variables.yml b/eng/common/core-templates/post-build/common-variables.yml
index d5627a994ae..db298ae16ba 100644
--- a/eng/common/core-templates/post-build/common-variables.yml
+++ b/eng/common/core-templates/post-build/common-variables.yml
@@ -11,8 +11,6 @@ variables:
- name: MaestroApiVersion
value: "2020-02-20"
- - name: SourceLinkCLIVersion
- value: 3.0.0
- name: SymbolToolVersion
value: 1.0.1
- name: BinlogToolVersion
diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml
index 0994189969f..8aa86e30491 100644
--- a/eng/common/core-templates/post-build/post-build.yml
+++ b/eng/common/core-templates/post-build/post-build.yml
@@ -9,6 +9,7 @@ parameters:
default: 3
values:
- 3
+ - 4
- name: BARBuildId
displayName: BAR Build Id
@@ -130,16 +131,30 @@ stages:
PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
is1ESPipeline: ${{ parameters.is1ESPipeline }}
- - task: DownloadBuildArtifacts@0
- displayName: Download Package Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: PackageArtifacts
- checkDownloadedFiles: true
+ - ${{ if ne(parameters.publishingInfraVersion, 4) }}:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: PackageArtifacts
+ checkDownloadedFiles: true
+ - ${{ if eq(parameters.publishingInfraVersion, 4) }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Pipeline Artifacts (V4)
+ inputs:
+ itemPattern: '*/packages/**/*.nupkg'
+ targetPath: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+ - task: CopyFiles@2
+ displayName: Flatten packages to PackageArtifacts
+ inputs:
+ SourceFolder: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+ Contents: '**/*.nupkg'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/PackageArtifacts'
+ flattenFolders: true
- task: PowerShell@2
displayName: Validate
@@ -173,16 +188,30 @@ stages:
PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
is1ESPipeline: ${{ parameters.is1ESPipeline }}
- - task: DownloadBuildArtifacts@0
- displayName: Download Package Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: PackageArtifacts
- checkDownloadedFiles: true
+ - ${{ if ne(parameters.publishingInfraVersion, 4) }}:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Package Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: PackageArtifacts
+ checkDownloadedFiles: true
+ - ${{ if eq(parameters.publishingInfraVersion, 4) }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Pipeline Artifacts (V4)
+ inputs:
+ itemPattern: '*/packages/**/*.nupkg'
+ targetPath: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+ - task: CopyFiles@2
+ displayName: Flatten packages to PackageArtifacts
+ inputs:
+ SourceFolder: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+ Contents: '**/*.nupkg'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/PackageArtifacts'
+ flattenFolders: true
# This is necessary whenever we want to publish/restore to an AzDO private feed
# Since sdk-task.ps1 tries to restore packages we need to do this authentication here
@@ -196,7 +225,7 @@ stages:
displayName: Validate
inputs:
filePath: eng\common\sdk-task.ps1
- arguments: -task SigningValidation -restore
+ arguments: -task SigningValidation -restore -msbuildEngine dotnet
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts'
/p:SignCheckExclusionsFile='$(System.DefaultWorkingDirectory)/eng/SignCheckExclusionsFile.txt'
${{ parameters.signingValidationAdditionalParameters }}
@@ -208,53 +237,20 @@ stages:
JobLabel: 'Signing'
BinlogToolVersion: $(BinlogToolVersion)
- - job:
- displayName: SourceLink Validation
- condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true')
- pool:
- # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: AzurePipelines-EO
- image: 1ESPT-Windows2025
- demands: Cmd
- os: windows
- # If it's not devdiv, it's dnceng
- ${{ else }}:
- ${{ if eq(parameters.is1ESPipeline, true) }}:
- name: $(DncEngInternalBuildPool)
- image: windows.vs2026.amd64
- os: windows
- ${{ else }}:
- name: $(DncEngInternalBuildPool)
- demands: ImageOverride -equals windows.vs2026.amd64
- steps:
- - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
- parameters:
- BARBuildId: ${{ parameters.BARBuildId }}
- PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }}
- is1ESPipeline: ${{ parameters.is1ESPipeline }}
-
- - task: DownloadBuildArtifacts@0
- displayName: Download Blob Artifacts
- inputs:
- buildType: specific
- buildVersionToDownload: specific
- project: $(AzDOProjectName)
- pipeline: $(AzDOPipelineId)
- buildId: $(AzDOBuildId)
- artifactName: BlobArtifacts
- checkDownloadedFiles: true
-
- - task: PowerShell@2
- displayName: Validate
- inputs:
- filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/sourcelink-validation.ps1
- arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/
- -ExtractPath $(Agent.BuildDirectory)/Extract/
- -GHRepoName $(Build.Repository.Name)
- -GHCommit $(Build.SourceVersion)
- -SourcelinkCliVersion $(SourceLinkCLIVersion)
- continueOnError: true
+ # SourceLink validation has been removed — the underlying CLI tool
+ # (targeting netcoreapp2.1) has not functioned for years.
+ # The enableSourceLinkValidation parameter is kept but ignored so
+ # existing pipelines that pass it are not broken.
+ # See https://github.com/dotnet/arcade/issues/16647
+ - ${{ if eq(parameters.enableSourceLinkValidation, 'true') }}:
+ - job:
+ displayName: 'SourceLink Validation Removed - please remove enableSourceLinkValidation from your pipeline'
+ pool: server
+ steps:
+ - task: Delay@1
+ displayName: 'Warning: SourceLink validation removed (see https://github.com/dotnet/arcade/issues/16647)'
+ inputs:
+ delayForMinutes: '0'
- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}:
- stage: publish_using_darc
@@ -317,7 +313,7 @@ stages:
scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1
arguments: >
-BuildId $(BARBuildId)
- -PublishingInfraVersion ${{ parameters.publishingInfraVersion }}
+ -PublishingInfraVersion 3
-AzdoToken '$(System.AccessToken)'
-WaitPublishingFinish true
-RequireDefaultChannels ${{ parameters.requireDefaultChannels }}
diff --git a/eng/common/core-templates/post-build/setup-maestro-vars.yml b/eng/common/core-templates/post-build/setup-maestro-vars.yml
index a7abd58c4bb..6dfa99ec5e3 100644
--- a/eng/common/core-templates/post-build/setup-maestro-vars.yml
+++ b/eng/common/core-templates/post-build/setup-maestro-vars.yml
@@ -8,12 +8,11 @@ steps:
- 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
- ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
- - task: DownloadBuildArtifacts@0
+ - task: DownloadPipelineArtifact@2
displayName: Download Release Configs
inputs:
- buildType: current
artifactName: ReleaseConfigs
- checkDownloadedFiles: true
+ targetPath: '$(Build.StagingDirectory)/ReleaseConfigs'
- task: AzureCLI@2
name: setReleaseVars
diff --git a/eng/common/core-templates/steps/component-governance.yml b/eng/common/core-templates/steps/component-governance.yml
deleted file mode 100644
index cf0649aa956..00000000000
--- a/eng/common/core-templates/steps/component-governance.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-parameters:
- disableComponentGovernance: false
- componentGovernanceIgnoreDirectories: ''
- is1ESPipeline: false
- displayName: 'Component Detection'
-
-steps:
-- ${{ if eq(parameters.disableComponentGovernance, 'true') }}:
- - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
- displayName: Set skipComponentGovernanceDetection variable
-- ${{ if ne(parameters.disableComponentGovernance, 'true') }}:
- - task: ComponentGovernanceComponentDetection@0
- continueOnError: true
- displayName: ${{ parameters.displayName }}
- inputs:
- ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml
index 003f7eae0fa..aad0a8aeda3 100644
--- a/eng/common/core-templates/steps/generate-sbom.yml
+++ b/eng/common/core-templates/steps/generate-sbom.yml
@@ -1,54 +1,14 @@
-# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.
-# PackageName - The name of the package this SBOM represents.
-# PackageVersion - The version of the package this SBOM represents.
-# ManifestDirPath - The path of the directory where the generated manifest files will be placed
-# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
-
parameters:
- PackageVersion: 11.0.0
- BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
- PackageName: '.NET'
- ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
- IgnoreDirectories: ''
- sbomContinueOnError: true
- is1ESPipeline: false
- # disable publishArtifacts if some other step is publishing the artifacts (like job.yml).
- publishArtifacts: true
+ PackageVersion: unused
+ BuildDropPath: unused
+ PackageName: unused
+ ManifestDirPath: unused
+ IgnoreDirectories: unused
+ sbomContinueOnError: unused
+ is1ESPipeline: unused
+ publishArtifacts: unused
steps:
-- task: PowerShell@2
- displayName: Prep for SBOM generation in (Non-linux)
- condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))
- inputs:
- filePath: ./eng/common/generate-sbom-prep.ps1
- arguments: ${{parameters.manifestDirPath}}
-
-# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461
- script: |
- chmod +x ./eng/common/generate-sbom-prep.sh
- ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}
- displayName: Prep for SBOM generation in (Linux)
- condition: eq(variables['Agent.Os'], 'Linux')
- continueOnError: ${{ parameters.sbomContinueOnError }}
-
-- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
- displayName: 'Generate SBOM manifest'
- continueOnError: ${{ parameters.sbomContinueOnError }}
- inputs:
- PackageName: ${{ parameters.packageName }}
- BuildDropPath: ${{ parameters.buildDropPath }}
- PackageVersion: ${{ parameters.packageVersion }}
- ManifestDirPath: ${{ parameters.manifestDirPath }}/$(ARTIFACT_NAME)
- ${{ if ne(parameters.IgnoreDirectories, '') }}:
- AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
-
-- ${{ if eq(parameters.publishArtifacts, 'true')}}:
- - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
- parameters:
- is1ESPipeline: ${{ parameters.is1ESPipeline }}
- args:
- displayName: Publish SBOM manifest
- continueOnError: ${{parameters.sbomContinueOnError}}
- targetPath: '${{ parameters.manifestDirPath }}'
- artifactName: $(ARTIFACT_NAME)
-
+ echo "##vso[task.logissue type=warning]Including generate-sbom.yml is deprecated, SBOM generation is handled 1ES PT now. Remove this include."
+ displayName: Issue generate-sbom.yml deprecation warning
diff --git a/eng/common/core-templates/steps/publish-logs.yml b/eng/common/core-templates/steps/publish-logs.yml
index a9ea99ba6aa..84a1922c73f 100644
--- a/eng/common/core-templates/steps/publish-logs.yml
+++ b/eng/common/core-templates/steps/publish-logs.yml
@@ -50,13 +50,15 @@ steps:
TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
condition: always()
-- template: /eng/common/core-templates/steps/publish-build-artifacts.yml
+- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
parameters:
is1ESPipeline: ${{ parameters.is1ESPipeline }}
args:
displayName: Publish Logs
- pathToPublish: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
- publishLocation: Container
- artifactName: PostBuildLogs
+ targetPath: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
+ artifactName: PostBuildLogs_${{ parameters.StageLabel }}_${{ parameters.JobLabel }}_Attempt$(System.JobAttempt)
continueOnError: true
condition: always()
+ retryCountOnTaskFailure: 10 # for any files being locked
+ isProduction: false # logs are non-production artifacts
+
diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml
index acf16ed3496..b75f59c428d 100644
--- a/eng/common/core-templates/steps/source-build.yml
+++ b/eng/common/core-templates/steps/source-build.yml
@@ -62,4 +62,4 @@ steps:
artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
continueOnError: true
condition: succeededOrFailed()
- sbomEnabled: false # we don't need SBOM for logs
+ isProduction: false # logs are non-production artifacts
diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake
index ff2dfdb4a5b..99d6dfe82dd 100644
--- a/eng/common/cross/toolchain.cmake
+++ b/eng/common/cross/toolchain.cmake
@@ -225,13 +225,19 @@ elseif(ILLUMOS)
locate_toolchain_exec(g++ CMAKE_CXX_COMPILER)
elseif(HAIKU)
set(CMAKE_SYSROOT "${CROSS_ROOTFS}")
- set(CMAKE_PROGRAM_PATH "${CMAKE_PROGRAM_PATH};${CROSS_ROOTFS}/cross-tools-x86_64/bin")
set(CMAKE_SYSTEM_PREFIX_PATH "${CROSS_ROOTFS}")
set(CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lssp")
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -lssp")
- locate_toolchain_exec(gcc CMAKE_C_COMPILER)
- locate_toolchain_exec(g++ CMAKE_CXX_COMPILER)
+ if ($ENV{CCC_CC} MATCHES ".*gcc.*")
+ set(CMAKE_PROGRAM_PATH "${CMAKE_PROGRAM_PATH};${CROSS_ROOTFS}/cross-tools-x86_64/bin")
+ locate_toolchain_exec(gcc CMAKE_C_COMPILER)
+ locate_toolchain_exec(g++ CMAKE_CXX_COMPILER)
+ else()
+ set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/cross-tools-x86_64")
+ set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/cross-tools-x86_64")
+ set(CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN "${CROSS_ROOTFS}/cross-tools-x86_64")
+ endif()
# let CMake set up the correct search paths
include(Platform/Haiku)
diff --git a/eng/common/darc-init.ps1 b/eng/common/darc-init.ps1
index e3374310563..a5be41db690 100644
--- a/eng/common/darc-init.ps1
+++ b/eng/common/darc-init.ps1
@@ -29,11 +29,11 @@ function InstallDarcCli ($darcVersion, $toolpath) {
Write-Host "Installing Darc CLI version $darcVersion..."
Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.'
if (-not $toolpath) {
- Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity -g"
- & "$dotnet" tool install $darcCliPackageName --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g
+ Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --source '$arcadeServicesSource' -v $verbosity -g"
+ & "$dotnet" tool install $darcCliPackageName --version $darcVersion --source "$arcadeServicesSource" -v $verbosity -g
}else {
- Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --add-source '$arcadeServicesSource' -v $verbosity --tool-path '$toolpath'"
- & "$dotnet" tool install $darcCliPackageName --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath"
+ Write-Host "'$dotnet' tool install $darcCliPackageName --version $darcVersion --source '$arcadeServicesSource' -v $verbosity --tool-path '$toolpath'"
+ & "$dotnet" tool install $darcCliPackageName --version $darcVersion --source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath"
}
}
diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh
index 9f5ad6b763b..b56d40e5706 100755
--- a/eng/common/darc-init.sh
+++ b/eng/common/darc-init.sh
@@ -73,9 +73,9 @@ function InstallDarcCli {
echo "Installing Darc CLI version $darcVersion..."
echo "You may need to restart your command shell if this is the first dotnet tool you have installed."
if [ -z "$toolpath" ]; then
- echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g)
+ echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --source "$arcadeServicesSource" -v $verbosity -g)
else
- echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath")
+ echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath")
fi
}
diff --git a/eng/common/dotnet-install.ps1 b/eng/common/dotnet-install.ps1
index 811f0f717f7..50ae6273768 100644
--- a/eng/common/dotnet-install.ps1
+++ b/eng/common/dotnet-install.ps1
@@ -10,7 +10,11 @@ Param(
. $PSScriptRoot\tools.ps1
-$dotnetRoot = Join-Path $RepoRoot '.dotnet'
+if (-not [string]::IsNullOrEmpty($env:DOTNET_GLOBAL_INSTALL_DIR)) {
+ $dotnetRoot = $env:DOTNET_GLOBAL_INSTALL_DIR
+} else {
+ $dotnetRoot = Join-Path $RepoRoot '.dotnet'
+}
$installdir = $dotnetRoot
try {
diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh
index 61f302bb677..1cb3f5abac2 100755
--- a/eng/common/dotnet-install.sh
+++ b/eng/common/dotnet-install.sh
@@ -80,7 +80,11 @@ case $cpuname in
;;
esac
-dotnetRoot="${repo_root}.dotnet"
+if [[ -n "${DOTNET_GLOBAL_INSTALL_DIR:-}" ]]; then
+ dotnetRoot="$DOTNET_GLOBAL_INSTALL_DIR"
+else
+ dotnetRoot="${repo_root}.dotnet"
+fi
if [[ $architecture != "" ]] && [[ $architecture != $buildarch ]]; then
dotnetRoot="$dotnetRoot/$architecture"
fi
diff --git a/eng/common/generate-sbom-prep.ps1 b/eng/common/generate-sbom-prep.ps1
deleted file mode 100644
index a0c7d792a76..00000000000
--- a/eng/common/generate-sbom-prep.ps1
+++ /dev/null
@@ -1,29 +0,0 @@
-Param(
- [Parameter(Mandatory=$true)][string] $ManifestDirPath # Manifest directory where sbom will be placed
-)
-
-. $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 $SbomGenerationDir))
-{
- 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"
-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
deleted file mode 100644
index b8ecca72bbf..00000000000
--- a/eng/common/generate-sbom-prep.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env bash
-
-source="${BASH_SOURCE[0]}"
-
-# resolve $SOURCE until the file is no longer a symlink
-while [[ -h $source ]]; do
- scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
- source="$(readlink "$source")"
-
- # if $source was a relative symlink, we need to resolve it relative to the path where the
- # symlink file was located
- [[ $source != /* ]] && source="$scriptroot/$source"
-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
-
-# 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
-
-echo "Artifact name before : "$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"
-
-exit 0
diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1
index fc0218a013d..672f4e2652e 100644
--- a/eng/common/post-build/redact-logs.ps1
+++ b/eng/common/post-build/redact-logs.ps1
@@ -49,8 +49,8 @@ try {
Write-Host "Installing Binlog redactor CLI..."
Write-Host "'$dotnet' new tool-manifest"
& "$dotnet" new tool-manifest
- Write-Host "'$dotnet' tool install $packageName --local --add-source '$PackageFeed' -v $verbosity --version $BinlogToolVersion"
- & "$dotnet" tool install $packageName --local --add-source "$PackageFeed" -v $verbosity --version $BinlogToolVersion
+ Write-Host "'$dotnet' tool install $packageName --local --source '$PackageFeed' -v $verbosity --version $BinlogToolVersion"
+ & "$dotnet" tool install $packageName --local --source "$PackageFeed" -v $verbosity --version $BinlogToolVersion
if (Test-Path $TokensFilePath) {
Write-Host "Adding additional sensitive data for redaction from file: " $TokensFilePath
diff --git a/eng/common/post-build/sourcelink-validation.ps1 b/eng/common/post-build/sourcelink-validation.ps1
deleted file mode 100644
index 1976ef70fb8..00000000000
--- a/eng/common/post-build/sourcelink-validation.ps1
+++ /dev/null
@@ -1,327 +0,0 @@
-param(
- [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where Symbols.NuGet packages to be checked are stored
- [Parameter(Mandatory=$true)][string] $ExtractPath, # Full path to directory where the packages will be extracted during validation
- [Parameter(Mandatory=$false)][string] $GHRepoName, # GitHub name of the repo including the Org. E.g., dotnet/arcade
- [Parameter(Mandatory=$false)][string] $GHCommit, # GitHub commit SHA used to build the packages
- [Parameter(Mandatory=$true)][string] $SourcelinkCliVersion # Version of SourceLink CLI to use
-)
-
-$ErrorActionPreference = 'Stop'
-Set-StrictMode -Version 2.0
-
-# `tools.ps1` checks $ci to perform some actions. Since the post-build
-# scripts don't necessarily execute in the same agent that run the
-# build.ps1/sh script this variable isn't automatically set.
-$ci = $true
-$disableConfigureToolsetImport = $true
-. $PSScriptRoot\..\tools.ps1
-
-# Cache/HashMap (File -> Exist flag) used to consult whether a file exist
-# in the repository at a specific commit point. This is populated by inserting
-# all files present in the repo at a specific commit point.
-$global:RepoFiles = @{}
-
-# Maximum number of jobs to run in parallel
-$MaxParallelJobs = 16
-
-$MaxRetries = 5
-$RetryWaitTimeInSeconds = 30
-
-# Wait time between check for system load
-$SecondsBetweenLoadChecks = 10
-
-if (!$InputPath -or !(Test-Path $InputPath)){
- Write-Host "No files to validate."
- ExitWithExitCode 0
-}
-
-$ValidatePackage = {
- param(
- [string] $PackagePath # Full path to a Symbols.NuGet package
- )
-
- . $using:PSScriptRoot\..\tools.ps1
-
- # Ensure input file exist
- if (!(Test-Path $PackagePath)) {
- Write-Host "Input file does not exist: $PackagePath"
- return [pscustomobject]@{
- result = 1
- packagePath = $PackagePath
- }
- }
-
- # Extensions for which we'll look for SourceLink information
- # For now we'll only care about Portable & Embedded PDBs
- $RelevantExtensions = @('.dll', '.exe', '.pdb')
-
- Write-Host -NoNewLine 'Validating ' ([System.IO.Path]::GetFileName($PackagePath)) '...'
-
- $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)
- $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId
- $FailedFiles = 0
-
- Add-Type -AssemblyName System.IO.Compression.FileSystem
-
- [System.IO.Directory]::CreateDirectory($ExtractPath) | Out-Null
-
- try {
- $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath)
-
- $zip.Entries |
- Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} |
- ForEach-Object {
- $FileName = $_.FullName
- $Extension = [System.IO.Path]::GetExtension($_.Name)
- $FakeName = -Join((New-Guid), $Extension)
- $TargetFile = Join-Path -Path $ExtractPath -ChildPath $FakeName
-
- # We ignore resource DLLs
- if ($FileName.EndsWith('.resources.dll')) {
- return [pscustomobject]@{
- result = 0
- packagePath = $PackagePath
- }
- }
-
- [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile, $true)
-
- $ValidateFile = {
- param(
- [string] $FullPath, # Full path to the module that has to be checked
- [string] $RealPath,
- [ref] $FailedFiles
- )
-
- $sourcelinkExe = "$env:USERPROFILE\.dotnet\tools"
- $sourcelinkExe = Resolve-Path "$sourcelinkExe\sourcelink.exe"
- $SourceLinkInfos = & $sourcelinkExe print-urls $FullPath | Out-String
-
- if ($LASTEXITCODE -eq 0 -and -not ([string]::IsNullOrEmpty($SourceLinkInfos))) {
- $NumFailedLinks = 0
-
- # We only care about Http addresses
- $Matches = (Select-String '(http[s]?)(:\/\/)([^\s,]+)' -Input $SourceLinkInfos -AllMatches).Matches
-
- if ($Matches.Count -ne 0) {
- $Matches.Value |
- ForEach-Object {
- $Link = $_
- $CommitUrl = "https://raw.githubusercontent.com/${using:GHRepoName}/${using:GHCommit}/"
-
- $FilePath = $Link.Replace($CommitUrl, "")
- $Status = 200
- $Cache = $using:RepoFiles
-
- $attempts = 0
-
- while ($attempts -lt $using:MaxRetries) {
- if ( !($Cache.ContainsKey($FilePath)) ) {
- try {
- $Uri = $Link -as [System.URI]
-
- if ($Link -match "submodules") {
- # Skip submodule links until sourcelink properly handles submodules
- $Status = 200
- }
- elseif ($Uri.AbsoluteURI -ne $null -and ($Uri.Host -match 'github' -or $Uri.Host -match 'githubusercontent')) {
- # Only GitHub links are valid
- $Status = (Invoke-WebRequest -Uri $Link -UseBasicParsing -Method HEAD -TimeoutSec 5).StatusCode
- }
- else {
- # If it's not a github link, we want to break out of the loop and not retry.
- $Status = 0
- $attempts = $using:MaxRetries
- }
- }
- catch {
- Write-Host $_
- $Status = 0
- }
- }
-
- if ($Status -ne 200) {
- $attempts++
-
- if ($attempts -lt $using:MaxRetries)
- {
- $attemptsLeft = $using:MaxRetries - $attempts
- Write-Warning "Download failed, $attemptsLeft attempts remaining, will retry in $using:RetryWaitTimeInSeconds seconds"
- Start-Sleep -Seconds $using:RetryWaitTimeInSeconds
- }
- else {
- if ($NumFailedLinks -eq 0) {
- if ($FailedFiles.Value -eq 0) {
- Write-Host
- }
-
- Write-Host "`tFile $RealPath has broken links:"
- }
-
- Write-Host "`t`tFailed to retrieve $Link"
-
- $NumFailedLinks++
- }
- }
- else {
- break
- }
- }
- }
- }
-
- if ($NumFailedLinks -ne 0) {
- $FailedFiles.value++
- $global:LASTEXITCODE = 1
- }
- }
- }
-
- &$ValidateFile $TargetFile $FileName ([ref]$FailedFiles)
- }
- }
- catch {
- Write-Host $_
- }
- finally {
- $zip.Dispose()
- }
-
- if ($FailedFiles -eq 0) {
- Write-Host 'Passed.'
- return [pscustomobject]@{
- result = 0
- packagePath = $PackagePath
- }
- }
- else {
- Write-PipelineTelemetryError -Category 'SourceLink' -Message "$PackagePath has broken SourceLink links."
- return [pscustomobject]@{
- result = 1
- packagePath = $PackagePath
- }
- }
-}
-
-function CheckJobResult(
- $result,
- $packagePath,
- [ref]$ValidationFailures,
- [switch]$logErrors) {
- if ($result -ne '0') {
- if ($logErrors) {
- Write-PipelineTelemetryError -Category 'SourceLink' -Message "$packagePath has broken SourceLink links."
- }
- $ValidationFailures.Value++
- }
-}
-
-function ValidateSourceLinkLinks {
- if ($GHRepoName -ne '' -and !($GHRepoName -Match '^[^\s\/]+/[^\s\/]+$')) {
- if (!($GHRepoName -Match '^[^\s-]+-[^\s]+$')) {
- Write-PipelineTelemetryError -Category 'SourceLink' -Message "GHRepoName should be in the format / or -. '$GHRepoName'"
- ExitWithExitCode 1
- }
- else {
- $GHRepoName = $GHRepoName -replace '^([^\s-]+)-([^\s]+)$', '$1/$2';
- }
- }
-
- if ($GHCommit -ne '' -and !($GHCommit -Match '^[0-9a-fA-F]{40}$')) {
- Write-PipelineTelemetryError -Category 'SourceLink' -Message "GHCommit should be a 40 chars hexadecimal string. '$GHCommit'"
- ExitWithExitCode 1
- }
-
- if ($GHRepoName -ne '' -and $GHCommit -ne '') {
- $RepoTreeURL = -Join('http://api.github.com/repos/', $GHRepoName, '/git/trees/', $GHCommit, '?recursive=1')
- $CodeExtensions = @('.cs', '.vb', '.fs', '.fsi', '.fsx', '.fsscript')
-
- try {
- # Retrieve the list of files in the repo at that particular commit point and store them in the RepoFiles hash
- $Data = Invoke-WebRequest $RepoTreeURL -UseBasicParsing | ConvertFrom-Json | Select-Object -ExpandProperty tree
-
- foreach ($file in $Data) {
- $Extension = [System.IO.Path]::GetExtension($file.path)
-
- if ($CodeExtensions.Contains($Extension)) {
- $RepoFiles[$file.path] = 1
- }
- }
- }
- catch {
- Write-Host "Problems downloading the list of files from the repo. Url used: $RepoTreeURL . Execution will proceed without caching."
- }
- }
- elseif ($GHRepoName -ne '' -or $GHCommit -ne '') {
- Write-Host 'For using the http caching mechanism both GHRepoName and GHCommit should be informed.'
- }
-
- if (Test-Path $ExtractPath) {
- Remove-Item $ExtractPath -Force -Recurse -ErrorAction SilentlyContinue
- }
-
- $ValidationFailures = 0
-
- # Process each NuGet package in parallel
- Get-ChildItem "$InputPath\*.symbols.nupkg" |
- ForEach-Object {
- Write-Host "Starting $($_.FullName)"
- Start-Job -ScriptBlock $ValidatePackage -ArgumentList $_.FullName | Out-Null
- $NumJobs = @(Get-Job -State 'Running').Count
-
- while ($NumJobs -ge $MaxParallelJobs) {
- Write-Host "There are $NumJobs validation jobs running right now. Waiting $SecondsBetweenLoadChecks seconds to check again."
- sleep $SecondsBetweenLoadChecks
- $NumJobs = @(Get-Job -State 'Running').Count
- }
-
- foreach ($Job in @(Get-Job -State 'Completed')) {
- $jobResult = Wait-Job -Id $Job.Id | Receive-Job
- CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$ValidationFailures) -LogErrors
- Remove-Job -Id $Job.Id
- }
- }
-
- foreach ($Job in @(Get-Job)) {
- $jobResult = Wait-Job -Id $Job.Id | Receive-Job
- CheckJobResult $jobResult.result $jobResult.packagePath ([ref]$ValidationFailures)
- Remove-Job -Id $Job.Id
- }
- if ($ValidationFailures -gt 0) {
- Write-PipelineTelemetryError -Category 'SourceLink' -Message "$ValidationFailures package(s) failed validation."
- ExitWithExitCode 1
- }
-}
-
-function InstallSourcelinkCli {
- $sourcelinkCliPackageName = 'sourcelink'
-
- $dotnetRoot = InitializeDotNetCli -install:$true
- $dotnet = "$dotnetRoot\dotnet.exe"
- $toolList = & "$dotnet" tool list --global
-
- if (($toolList -like "*$sourcelinkCliPackageName*") -and ($toolList -like "*$sourcelinkCliVersion*")) {
- Write-Host "SourceLink CLI version $sourcelinkCliVersion is already installed."
- }
- else {
- Write-Host "Installing SourceLink CLI version $sourcelinkCliVersion..."
- Write-Host 'You may need to restart your command window if this is the first dotnet tool you have installed.'
- & "$dotnet" tool install $sourcelinkCliPackageName --version $sourcelinkCliVersion --verbosity "minimal" --global
- }
-}
-
-try {
- InstallSourcelinkCli
-
- foreach ($Job in @(Get-Job)) {
- Remove-Job -Id $Job.Id
- }
-
- ValidateSourceLinkLinks
-}
-catch {
- Write-Host $_.Exception
- Write-Host $_.ScriptStackTrace
- Write-PipelineTelemetryError -Category 'SourceLink' -Message $_
- ExitWithExitCode 1
-}
diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1
index 4017ff15ebf..68119de603e 100644
--- a/eng/common/sdk-task.ps1
+++ b/eng/common/sdk-task.ps1
@@ -66,20 +66,7 @@ try {
if( $msbuildEngine -eq "vs") {
# Ensure desktop MSBuild is available for sdk tasks.
- if( -not ($GlobalJson.tools.PSObject.Properties.Name -contains "vs" )) {
- $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 "18.0.0" -MemberType NoteProperty
- }
- if ($GlobalJson.tools."xcopy-msbuild".Trim() -ine "none") {
- $xcopyMSBuildToolsFolder = InitializeXCopyMSBuild $GlobalJson.tools."xcopy-msbuild" -install $true
- }
- if ($xcopyMSBuildToolsFolder -eq $null) {
- throw 'Unable to get xcopy downloadable version of msbuild'
- }
-
- $global:_MSBuildExe = "$($xcopyMSBuildToolsFolder)\MSBuild\Current\Bin\MSBuild.exe"
+ $global:_MSBuildExe = InitializeVisualStudioMSBuild
}
$taskProject = GetSdkTaskProject $task
diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md
index cdc62e72b07..f772aa3d78f 100644
--- a/eng/common/template-guidance.md
+++ b/eng/common/template-guidance.md
@@ -81,7 +81,6 @@ eng\common\
publish-build-artifacts.yml (logic)
publish-pipeline-artifacts.yml (logic)
component-governance.yml (shim)
- generate-sbom.yml (shim)
publish-logs.yml (shim)
retain-build.yml (shim)
send-to-helix.yml (shim)
@@ -104,7 +103,6 @@ eng\common\
setup-maestro-vars.yml (logic)
steps\
component-governance.yml (logic)
- generate-sbom.yml (logic)
publish-build-artifacts.yml (redirect)
publish-logs.yml (logic)
publish-pipeline-artifacts.yml (redirect)
diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml
index f70224eaa45..d68e9fbc265 100644
--- a/eng/common/templates-official/job/job.yml
+++ b/eng/common/templates-official/job/job.yml
@@ -1,24 +1,15 @@
parameters:
-# Sbom related params
- enableSbom: true
runAsPublic: false
- PackageVersion: 9.0.0
- BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
+# Sbom related params, unused now and can eventually be removed
+ enableSbom: unused
+ PackageVersion: unused
+ BuildDropPath: unused
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:
@@ -26,12 +17,19 @@ jobs:
outputs:
- ${{ if ne(parameters.artifacts.publish, '') }}:
- ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}:
- - output: buildArtifacts
+ - output: pipelineArtifact
displayName: Publish pipeline artifacts
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
- ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
- condition: always()
- retryCountOnTaskFailure: 10 # for any logs being locked
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+ artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
+ condition: succeeded()
+ retryCountOnTaskFailure: 10 # for any files being locked
+ continueOnError: true
+ - output: pipelineArtifact
+ displayName: Publish pipeline artifacts
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+ artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}_Attempt$(System.JobAttempt)
+ condition: not(succeeded())
+ retryCountOnTaskFailure: 10 # for any files being locked
continueOnError: true
- ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
- output: pipelineArtifact
@@ -40,8 +38,8 @@ jobs:
displayName: 'Publish logs'
continueOnError: true
condition: always()
- retryCountOnTaskFailure: 10 # for any logs being locked
- sbomEnabled: false # we don't need SBOM for logs
+ retryCountOnTaskFailure: 10 # for any files being locked
+ isProduction: false # logs are non-production artifacts
- ${{ if eq(parameters.enablePublishBuildArtifacts, true) }}:
- output: pipelineArtifact
@@ -50,7 +48,8 @@ jobs:
artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
continueOnError: true
condition: always()
- sbomEnabled: false # we don't need SBOM for logs
+ retryCountOnTaskFailure: 10 # for any files being locked
+ isProduction: false # logs are non-production artifacts
- ${{ if eq(parameters.enableBuildRetry, 'true') }}:
- output: pipelineArtifact
@@ -58,14 +57,20 @@ jobs:
artifactName: 'BuildConfiguration'
displayName: 'Publish build retry configuration'
continueOnError: true
- sbomEnabled: false # we don't need SBOM for BuildConfiguration
+ retryCountOnTaskFailure: 10 # for any files being locked
+ isProduction: false # BuildConfiguration is a non-production artifact
- - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}:
+ # V4 publishing: automatically publish staged artifacts as a pipeline artifact.
+ # The artifact name matches the SDK's FutureArtifactName ($(System.PhaseName)_Artifacts),
+ # which is encoded in the asset manifest for downstream publishing to discover.
+ # Jobs can opt in by setting enablePublishing: true.
+ - ${{ if and(eq(parameters.publishingVersion, 4), eq(parameters.enablePublishing, 'true')) }}:
- output: pipelineArtifact
- displayName: Publish SBOM manifest
+ displayName: 'Publish V4 pipeline artifacts'
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+ artifactName: '$(System.PhaseName)_Artifacts'
continueOnError: true
- targetPath: $(Build.ArtifactStagingDirectory)/sbom
- artifactName: $(ARTIFACT_NAME)
+ retryCountOnTaskFailure: 10 # for any files being locked
# add any outputs provided via root yaml
- ${{ if ne(parameters.templateContext.outputs, '') }}:
diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml
deleted file mode 100644
index 30bb3985ca2..00000000000
--- a/eng/common/templates-official/steps/component-governance.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-steps:
-- template: /eng/common/core-templates/steps/component-governance.yml
- parameters:
- is1ESPipeline: true
-
- ${{ each parameter in parameters }}:
- ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
index 172f9f0fdc9..9e5981365e5 100644
--- a/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
+++ b/eng/common/templates-official/steps/publish-pipeline-artifacts.yml
@@ -24,5 +24,7 @@ steps:
artifactName: ${{ parameters.args.artifactName }}
${{ if parameters.args.properties }}:
properties: ${{ parameters.args.properties }}
- ${{ if parameters.args.sbomEnabled }}:
+ ${{ if ne(parameters.args.sbomEnabled, '') }}:
sbomEnabled: ${{ parameters.args.sbomEnabled }}
+ ${{ if ne(parameters.args.isProduction, '') }}:
+ isProduction: ${{ parameters.args.isProduction }}
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 7f1b5d97d1a..5e261f34db4 100644
--- a/eng/common/templates/job/job.yml
+++ b/eng/common/templates/job/job.yml
@@ -1,12 +1,12 @@
parameters:
enablePublishBuildArtifacts: false
- disableComponentGovernance: ''
- componentGovernanceIgnoreDirectories: ''
-# Sbom related params
- enableSbom: true
runAsPublic: false
- PackageVersion: 9.0.0
- BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts'
+# CG related params, unused now and can eventually be removed
+ disableComponentGovernance: unused
+# Sbom related params, unused now and can eventually be removed
+ enableSbom: unused
+ PackageVersion: unused
+ BuildDropPath: unused
jobs:
- template: /eng/common/core-templates/job/job.yml
@@ -21,32 +21,34 @@ jobs:
- ${{ 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
- ${{ else }}:
- disableComponentGovernance: ${{ parameters.disableComponentGovernance }}
- componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
+ # we don't run CG in public
+ - ${{ if eq(variables['System.TeamProject'], 'public') }}:
+ - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
+ displayName: Set skipComponentGovernanceDetection variable
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
+ - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
parameters:
is1ESPipeline: false
args:
displayName: Publish pipeline artifacts
- pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts'
- publishLocation: Container
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}
continueOnError: true
- condition: always()
- retryCountOnTaskFailure: 10 # for any logs being locked
+ condition: succeeded()
+ retryCountOnTaskFailure: 10 # for any files being locked
+ - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
+ parameters:
+ is1ESPipeline: false
+ args:
+ displayName: Publish pipeline artifacts
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
+ artifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }}_Attempt$(System.JobAttempt)
+ continueOnError: true
+ condition: not(succeeded())
+ retryCountOnTaskFailure: 10 # for any files being locked
- ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}:
- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
parameters:
@@ -57,8 +59,7 @@ jobs:
displayName: 'Publish logs'
continueOnError: true
condition: always()
- retryCountOnTaskFailure: 10 # for any logs being locked
- sbomEnabled: false # we don't need SBOM for logs
+ retryCountOnTaskFailure: 10 # for any files being locked
- ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}:
- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
@@ -70,7 +71,7 @@ jobs:
artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
continueOnError: true
condition: always()
- sbomEnabled: false
+ retryCountOnTaskFailure: 10 # for any files being locked
- ${{ if eq(parameters.enableBuildRetry, 'true') }}:
- template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
@@ -81,4 +82,4 @@ jobs:
artifactName: 'BuildConfiguration'
displayName: 'Publish build retry configuration'
continueOnError: true
- sbomEnabled: false # we don't need SBOM for BuildConfiguration
+ retryCountOnTaskFailure: 10 # for any files being locked
diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml
deleted file mode 100644
index c12a5f8d21d..00000000000
--- a/eng/common/templates/steps/component-governance.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-steps:
-- template: /eng/common/core-templates/steps/component-governance.yml
- parameters:
- is1ESPipeline: false
-
- ${{ each parameter in parameters }}:
- ${{ parameter.key }}: ${{ parameter.value }}
diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1
index 6710ffb884b..0e281df8cae 100644
--- a/eng/common/tools.ps1
+++ b/eng/common/tools.ps1
@@ -168,6 +168,12 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
$env:DOTNET_CLI_TELEMETRY_OPTOUT=1
}
+ # Keep repo builds isolated from machine-installed SDK state and workload advertising.
+ # This avoids preview SDK builds picking up mismatched workloads on CI images.
+ $env:DOTNET_MULTILEVEL_LOOKUP = '0'
+ $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = '1'
+ $env:DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE = '1'
+
# Find the first path on %PATH% that contains the dotnet.exe
if ($useInstalledDotNetCli -and (-not $globalJsonHasRuntimes) -and ($env:DOTNET_INSTALL_DIR -eq $null)) {
$dotnetExecutable = GetExecutableFileName 'dotnet'
@@ -185,7 +191,11 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
if ((-not $globalJsonHasRuntimes) -and (-not [string]::IsNullOrEmpty($env:DOTNET_INSTALL_DIR)) -and (Test-Path(Join-Path $env:DOTNET_INSTALL_DIR "sdk\$dotnetSdkVersion"))) {
$dotnetRoot = $env:DOTNET_INSTALL_DIR
} else {
- $dotnetRoot = Join-Path $RepoRoot '.dotnet'
+ if (-not [string]::IsNullOrEmpty($env:DOTNET_GLOBAL_INSTALL_DIR)) {
+ $dotnetRoot = $env:DOTNET_GLOBAL_INSTALL_DIR
+ } else {
+ $dotnetRoot = Join-Path $RepoRoot '.dotnet'
+ }
if (-not (Test-Path(Join-Path $dotnetRoot "sdk\$dotnetSdkVersion"))) {
if ($install) {
@@ -226,6 +236,9 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) {
Write-PipelinePrependPath -Path $dotnetRoot
Write-PipelineSetVariable -Name 'DOTNET_NOLOGO' -Value '1'
+ Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0'
+ Write-PipelineSetVariable -Name 'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' -Value '1'
+ Write-PipelineSetVariable -Name 'DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE' -Value '1'
return $global:_DotNetInstallDir = $dotnetRoot
}
@@ -375,12 +388,11 @@ function InstallDotNet([string] $dotnetRoot,
#
# 1. MSBuild from an active VS command prompt
# 2. MSBuild from a compatible VS installation
-# 3. MSBuild from the xcopy tool package
#
# Returns full path to msbuild.exe.
# Throws on failure.
#
-function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = $null) {
+function InitializeVisualStudioMSBuild([object]$vsRequirements = $null) {
if (-not (IsWindowsPlatform)) {
throw "Cannot initialize Visual Studio on non-Windows"
}
@@ -390,13 +402,7 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
}
# Minimum VS version to require.
- $vsMinVersionReqdStr = '17.7'
- $vsMinVersionReqd = [Version]::new($vsMinVersionReqdStr)
-
- # 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/18.0.0
- $defaultXCopyMSBuildVersion = '18.0.0'
+ $vsMinVersionReqdStr = '18.0'
if (!$vsRequirements) {
if (Get-Member -InputObject $GlobalJson.tools -Name 'vs') {
@@ -426,46 +432,16 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements =
}
}
- # Locate Visual Studio installation or download x-copy msbuild.
+ # Locate Visual Studio installation.
$vsInfo = LocateVisualStudio $vsRequirements
- if ($vsInfo -ne $null -and $env:ForceUseXCopyMSBuild -eq $null) {
+ if ($vsInfo -ne $null) {
# Ensure vsInstallDir has a trailing slash
$vsInstallDir = Join-Path $vsInfo.installationPath "\"
$vsMajorVersion = $vsInfo.installationVersion.Split('.')[0]
InitializeVisualStudioEnvironmentVariables $vsInstallDir $vsMajorVersion
} else {
- if (Get-Member -InputObject $GlobalJson.tools -Name 'xcopy-msbuild') {
- $xcopyMSBuildVersion = $GlobalJson.tools.'xcopy-msbuild'
- $vsMajorVersion = $xcopyMSBuildVersion.Split('.')[0]
- } else {
- #if vs version provided in global.json is incompatible (too low) then use the default version for xcopy msbuild download
- if($vsMinVersion -lt $vsMinVersionReqd){
- Write-Host "Using xcopy-msbuild version of $defaultXCopyMSBuildVersion since VS version $vsMinVersionStr provided in global.json is not compatible"
- $xcopyMSBuildVersion = $defaultXCopyMSBuildVersion
- $vsMajorVersion = $xcopyMSBuildVersion.Split('.')[0]
- }
- else{
- # If the VS version IS compatible, look for an xcopy msbuild package
- # with a version matching VS.
- # Note: If this version does not exist, then an explicit version of xcopy msbuild
- # can be specified in global.json. This will be required for pre-release versions of msbuild.
- $vsMajorVersion = $vsMinVersion.Major
- $vsMinorVersion = $vsMinVersion.Minor
- $xcopyMSBuildVersion = "$vsMajorVersion.$vsMinorVersion.0"
- }
- }
-
- $vsInstallDir = $null
- if ($xcopyMSBuildVersion.Trim() -ine "none") {
- $vsInstallDir = InitializeXCopyMSBuild $xcopyMSBuildVersion $install
- if ($vsInstallDir -eq $null) {
- throw "Could not xcopy msbuild. Please check that package 'Microsoft.DotNet.Arcade.MSBuild.Xcopy @ $xcopyMSBuildVersion' exists on feed 'dotnet-eng'."
- }
- }
- if ($vsInstallDir -eq $null) {
- throw 'Unable to find Visual Studio that has required version and components installed'
- }
+ throw 'Unable to find Visual Studio that has required version and components installed'
}
$msbuildVersionDir = if ([int]$vsMajorVersion -lt 16) { "$vsMajorVersion.0" } else { "Current" }
@@ -492,38 +468,6 @@ function InitializeVisualStudioEnvironmentVariables([string] $vsInstallDir, [str
}
}
-function InstallXCopyMSBuild([string]$packageVersion) {
- return InitializeXCopyMSBuild $packageVersion -install $true
-}
-
-function InitializeXCopyMSBuild([string]$packageVersion, [bool]$install) {
- $packageName = 'Microsoft.DotNet.Arcade.MSBuild.Xcopy'
- $packageDir = Join-Path $ToolsDir "msbuild\$packageVersion"
- $packagePath = Join-Path $packageDir "$packageName.$packageVersion.nupkg"
-
- if (!(Test-Path $packageDir)) {
- if (!$install) {
- return $null
- }
-
- Create-Directory $packageDir
-
- Write-Host "Downloading $packageName $packageVersion"
- $ProgressPreference = 'SilentlyContinue' # Don't display the console progress UI - it's a huge perf hit
- Retry({
- Invoke-WebRequest "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/flat2/$packageName/$packageVersion/$packageName.$packageVersion.nupkg" -UseBasicParsing -OutFile $packagePath
- })
-
- if (!(Test-Path $packagePath)) {
- Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "See https://dev.azure.com/dnceng/internal/_wiki/wikis/DNCEng%20Services%20Wiki/1074/Updating-Microsoft.DotNet.Arcade.MSBuild.Xcopy-WAS-RoslynTools.MSBuild-(xcopy-msbuild)-generation?anchor=troubleshooting for help troubleshooting issues with XCopy MSBuild"
- throw
- }
- Unzip $packagePath $packageDir
- }
-
- return Join-Path $packageDir 'tools'
-}
-
#
# Locates Visual Studio instance that meets the minimal requirements specified by tools.vs object in global.json.
#
@@ -632,7 +576,7 @@ function InitializeBuildTool() {
$buildTool = @{ Path = $dotnetPath; Command = 'msbuild'; Tool = 'dotnet'; Framework = 'net' }
} elseif ($msbuildEngine -eq "vs") {
try {
- $msbuildPath = InitializeVisualStudioMSBuild -install:$restore
+ $msbuildPath = InitializeVisualStudioMSBuild
} catch {
Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_
ExitWithExitCode 1
@@ -684,11 +628,7 @@ function GetSdkTaskProject([string]$taskName) {
if (Test-Path $proj) {
return $proj
}
- # TODO: Remove this fallback once all supported versions use the new layout.
- $legacyProj = Join-Path $toolsetDir "SdkTasks\$taskName.proj"
- if (Test-Path $legacyProj) {
- return $legacyProj
- }
+
throw "Unable to find $taskName.proj in toolset at: $toolsetDir"
}
@@ -745,32 +685,33 @@ function InitializeToolset() {
ExitWithExitCode 1
}
- $downloadArgs = @("package", "download", "Microsoft.DotNet.Arcade.Sdk@$toolsetVersion", "--prerelease", "--output", "$nugetCache")
- if ($env:NUGET_CONFIG) {
+ $downloadArgs = @("package", "download", "Microsoft.DotNet.Arcade.Sdk@$toolsetVersion", "--verbosity", "minimal", "--prerelease", "--output", "$nugetCache")
+ $nugetConfig = $env:NUGET_CONFIG
+ if (-not $nugetConfig) {
+ # Search for any variation of nuget.config in the RepoRoot
+ $configFile = Get-ChildItem -Path $RepoRoot -File | Where-Object { $_.Name -ieq "nuget.config" } | Select-Object -First 1
+
+ if ($configFile) {
+ $nugetConfig = $configFile.FullName
+ }
+ }
+
+ if ($nugetConfig) {
$downloadArgs += "--configfile"
- $downloadArgs += $env:NUGET_CONFIG
+ $downloadArgs += $nugetConfig
}
DotNet @downloadArgs
$packageDir = Join-Path $nugetCache (Join-Path 'microsoft.dotnet.arcade.sdk' $toolsetVersion)
$packageToolsetDir = Join-Path $packageDir 'toolset'
- $packageToolsDir = Join-Path $packageDir 'tools'
- # TODO: Remove the tools/ check once all supported versions have the toolset folder.
- if (!(Test-Path $packageToolsetDir) -and !(Test-Path $packageToolsDir)) {
+ if (!(Test-Path $packageToolsetDir)) {
Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Arcade SDK package does not contain a toolset or tools folder: $packageDir"
ExitWithExitCode 3
}
New-Item -ItemType Directory -Path $toolsetToolsDir -Force | Out-Null
-
- # Copy toolset if present at the package root (new layout), otherwise fall back to tools
- if (Test-Path $packageToolsetDir) {
- Copy-Item -Path "$packageToolsetDir\*" -Destination $toolsetToolsDir -Recurse -Force
- } else {
- # TODO: Remove this fallback once all supported versions have the toolset folder.
- Copy-Item -Path "$packageToolsDir\*" -Destination $toolsetToolsDir -Recurse -Force
- }
+ Copy-Item -Path "$packageToolsetDir\*" -Destination $toolsetToolsDir -Recurse -Force
if (Test-Path $buildProjPath) {
$toolsetBuildProj = $buildProjPath
@@ -897,6 +838,10 @@ function MSBuild-Core() {
$cmdArgs = "$($buildTool.Command) /m /nologo /clp:Summary /v:$verbosity /nr:$nodeReuse /p:ContinuousIntegrationBuild=$ci"
+ if ($ci -and $buildTool.Tool -eq 'dotnet') {
+ $cmdArgs += ' /p:MSBuildEnableWorkloadResolver=false'
+ }
+
# Add -mt flag for MSBuild multithreaded mode if enabled via environment variable
if ($env:MSBUILD_MT_ENABLED -eq "1") {
$cmdArgs += ' -mt'
@@ -1007,6 +952,12 @@ Create-Directory $ToolsetDir
Create-Directory $TempDir
Create-Directory $LogDir
+# Direct MSBuild crash diagnostics (MSB4166 failure.txt files) to a known location
+# under artifacts/log so they are captured as build artifacts in CI.
+if (-not $env:MSBUILDDEBUGPATH) {
+ $env:MSBUILDDEBUGPATH = Join-Path $LogDir 'MsbuildDebugLogs'
+}
+
Write-PipelineSetVariable -Name 'Artifacts' -Value $ArtifactsDir
Write-PipelineSetVariable -Name 'Artifacts.Toolset' -Value $ToolsetDir
Write-PipelineSetVariable -Name 'Artifacts.Log' -Value $LogDir
diff --git a/eng/common/tools.sh b/eng/common/tools.sh
index d2339eb21d5..5ff37cfb700 100755
--- a/eng/common/tools.sh
+++ b/eng/common/tools.sh
@@ -126,6 +126,12 @@ function InitializeDotNetCli {
export DOTNET_CLI_TELEMETRY_OPTOUT=1
fi
+ # Keep repo builds isolated from machine-installed SDK state and workload advertising.
+ # This avoids preview SDK builds picking up mismatched workloads on CI images.
+ export DOTNET_MULTILEVEL_LOOKUP=0
+ export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
+ export DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE=1
+
# LTTNG is the logging infrastructure used by Core CLR. Need this variable set
# so it doesn't output warnings to the console.
export LTTNG_HOME="$HOME"
@@ -148,7 +154,11 @@ function InitializeDotNetCli {
if [[ $global_json_has_runtimes == false && -n "${DOTNET_INSTALL_DIR:-}" && -d "$DOTNET_INSTALL_DIR/sdk/$dotnet_sdk_version" ]]; then
dotnet_root="$DOTNET_INSTALL_DIR"
else
- dotnet_root="${repo_root}.dotnet"
+ if [[ -n "${DOTNET_GLOBAL_INSTALL_DIR:-}" ]]; then
+ dotnet_root="$DOTNET_GLOBAL_INSTALL_DIR"
+ else
+ dotnet_root="${repo_root}.dotnet"
+ fi
export DOTNET_INSTALL_DIR="$dotnet_root"
@@ -167,6 +177,9 @@ function InitializeDotNetCli {
Write-PipelinePrependPath -path "$dotnet_root"
Write-PipelineSetVariable -name "DOTNET_NOLOGO" -value "1"
+ Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0"
+ Write-PipelineSetVariable -name "DOTNET_SKIP_FIRST_TIME_EXPERIENCE" -value "1"
+ Write-PipelineSetVariable -name "DOTNET_CLI_WORKLOAD_UPDATE_NOTIFY_DISABLE" -value "1"
# return value
_InitializeDotNetCli="$dotnet_root"
@@ -426,29 +439,32 @@ function InitializeToolset {
ExitWithExitCode 2
fi
- local download_args=("package" "download" "Microsoft.DotNet.Arcade.Sdk@$toolset_version" "--prerelease" "--output" "$_GetNuGetPackageCachePath")
- if [[ -n "${NUGET_CONFIG:-}" ]]; then
- download_args+=("--configfile" "$NUGET_CONFIG")
+ local download_args=("package" "download" "Microsoft.DotNet.Arcade.Sdk@$toolset_version" "--verbosity" "minimal" "--prerelease" "--output" "$_GetNuGetPackageCachePath")
+ local nuget_config="${NUGET_CONFIG:-}"
+ if [[ -z "$nuget_config" ]]; then
+ # Search for any variation of nuget.config in the RepoRoot
+ local found_config
+ found_config=$(find "$repo_root" -maxdepth 1 -type f -iname "nuget.config" -print -quit)
+
+ if [[ -n "$found_config" ]]; then
+ nuget_config="$found_config"
+ fi
+ fi
+
+ if [[ -n "$nuget_config" ]]; then
+ download_args+=("--configfile" "$nuget_config")
fi
DotNet "${download_args[@]}"
local package_dir="$_GetNuGetPackageCachePath/microsoft.dotnet.arcade.sdk/$toolset_version"
- # TODO: Remove the tools/ check once all supported versions have the toolset folder.
- if [[ ! -d "$package_dir/toolset" && ! -d "$package_dir/tools" ]]; then
- Write-PipelineTelemetryError -category 'InitializeToolset' "Arcade SDK package does not contain a toolset or tools folder: $package_dir"
+ if [[ ! -d "$package_dir/toolset" ]]; then
+ Write-PipelineTelemetryError -category 'InitializeToolset' "Arcade SDK package does not contain a toolset folder: $package_dir"
ExitWithExitCode 3
fi
mkdir -p "$toolset_tools_dir"
-
- # Copy toolset if present at the package root (new layout), otherwise fall back to tools
- if [[ -d "$package_dir/toolset" ]]; then
- cp -r "$package_dir/toolset/." "$toolset_tools_dir"
- else
- # TODO: Remove this fallback once all supported versions have the toolset folder.
- cp -r "$package_dir/tools/." "$toolset_tools_dir"
- fi
+ cp -r "$package_dir/toolset/." "$toolset_tools_dir"
if [[ -a "$toolset_tools_dir/Build.proj" ]]; then
toolset_build_proj="$toolset_tools_dir/Build.proj"
@@ -575,7 +591,12 @@ function MSBuild-Core {
warnnotaserror_switch="/warnnotaserror:$warn_not_as_error /p:AdditionalWarningsNotAsErrors=$warn_not_as_error"
fi
- RunBuildTool "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch $mt_switch $warnnotaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@"
+ local workload_resolver_switch=""
+ if [[ "$ci" == true && -n "${_InitializeBuildToolCommand:-}" ]]; then
+ workload_resolver_switch="/p:MSBuildEnableWorkloadResolver=false"
+ fi
+
+ RunBuildTool "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch $mt_switch $warnnotaserror_switch $workload_resolver_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@"
}
function GetDarc {
@@ -600,12 +621,7 @@ function GetSdkTaskProject {
echo "$proj"
return
fi
- # TODO: Remove this fallback once all supported versions use the new layout.
- local legacyProj="$toolsetDir/SdkTasks/$taskName.proj"
- if [[ -a "$legacyProj" ]]; then
- echo "$legacyProj"
- return
- fi
+
Write-PipelineTelemetryError -category 'Build' "Unable to find $taskName.proj in toolset at: $toolsetDir"
ExitWithExitCode 3
}
@@ -645,6 +661,12 @@ mkdir -p "$toolset_dir"
mkdir -p "$temp_dir"
mkdir -p "$log_dir"
+# Direct MSBuild crash diagnostics (MSB4166 failure.txt files) to a known location
+# under artifacts/log so they are captured as build artifacts in CI.
+if [[ -z "${MSBUILDDEBUGPATH:-}" ]]; then
+ export MSBUILDDEBUGPATH="$log_dir/MsbuildDebugLogs"
+fi
+
Write-PipelineSetVariable -name "Artifacts" -value "$artifacts_dir"
Write-PipelineSetVariable -name "Artifacts.Toolset" -value "$toolset_dir"
Write-PipelineSetVariable -name "Artifacts.Log" -value "$log_dir"
diff --git a/eng/pipelines/runtime-perf-jobs.yml b/eng/pipelines/runtime-perf-jobs.yml
index a37eef06f18..3b9493cc0ee 100644
--- a/eng/pipelines/runtime-perf-jobs.yml
+++ b/eng/pipelines/runtime-perf-jobs.yml
@@ -56,23 +56,22 @@ parameters:
type: object
default:
enabled: true
- # Temporarily disabling cobalt jobs because the cobalt machines are offline
- name: cobaltMicro
type: object
default:
- enabled: false
+ enabled: true
configs:
- linux_arm64
- name: cobaltSveMicro
type: object
default:
- enabled: false
+ enabled: true
configs:
- linux_arm64
- name: cobaltMicroR2RInterpreter
type: object
default:
- enabled: false
+ enabled: true
configs:
- linux_arm64
- name: androidCoreclrR2r
diff --git a/eng/pipelines/sdk-perf-jobs.yml b/eng/pipelines/sdk-perf-jobs.yml
index 4c3a62d1a72..c3c87fca015 100644
--- a/eng/pipelines/sdk-perf-jobs.yml
+++ b/eng/pipelines/sdk-perf-jobs.yml
@@ -17,6 +17,43 @@ jobs:
# Public correctness jobs
######################################################
+- ${{ if parameters.runPublicJobs }}:
+ - job: Tooling_Tests_Windows
+ displayName: Tooling Tests (Windows)
+ timeoutInMinutes: 30
+ condition: and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))
+ pool:
+ vmImage: windows-2022
+
+ steps:
+ - task: UseDotNet@2
+ displayName: Install .NET 8.0
+ inputs:
+ version: 8.0.x
+
+ - task: UseDotNet@2
+ displayName: Install .NET 10.0
+ inputs:
+ version: 10.0.x
+ includePreviewVersions: true
+
+ - task: UseDotNet@2
+ displayName: Install .NET 11.0
+ inputs:
+ version: 11.0.x
+ includePreviewVersions: true
+
+ - pwsh: |
+ $ErrorActionPreference = 'Stop'
+ $PSNativeCommandUseErrorActionPreference = $true
+
+ dotnet test src\tools\ResultsComparer.Tests\ResultsComparer.Tests.csproj --configuration Release --framework net11.0 --nologo --verbosity minimal
+ dotnet test src\tools\Reporting\Reporting.Tests\Reporting.Tests.csproj --configuration Release --framework net11.0 --nologo --verbosity minimal
+ dotnet test src\tools\CertHelperTests\CertRotatorTests.csproj --configuration Release --framework net10.0 --nologo --verbosity minimal
+ dotnet test src\tests\harness\BenchmarkDotNet.Extensions.Tests\BenchmarkDotNet.Extensions.Tests.csproj --configuration Release --framework net11.0 -p:PERFLAB_TARGET_FRAMEWORKS=net10.0 --nologo --verbosity minimal
+ dotnet test src\tools\ScenarioMeasurement\Startup.Tests\Startup.Tests.csproj --configuration Release --nologo --verbosity minimal
+ displayName: Run tooling tests
+
- ${{ if parameters.runPublicJobs }}:
# Scenario benchmarks
diff --git a/gc-azure-pipelines.yml b/gc-azure-pipelines.yml
index cf6b208a8ee..1d1fd31fb48 100644
--- a/gc-azure-pipelines.yml
+++ b/gc-azure-pipelines.yml
@@ -1,5 +1,5 @@
-# Project: src\benchmarks\gc\GC.Infrastructure\GC.Infrastructure.NotebookTests\GC.Infrastructure.NotebookTests.csproj.
-# Output: artifacts\bin\GC.Infrastructure.NotebookTests\Debug\net8.0\GC.Infrastructure.NotebookTests.dll
+# Project: src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core.UnitTests/GC.Infrastructure.Core.UnitTests.csproj.
+# Output: artifacts\bin\GC.Infrastructure.Core.UnitTests\Debug\net8.0\GC.Infrastructure.Core.UnitTests.dll
resources:
containers:
@@ -26,15 +26,15 @@ pr:
jobs:
# TODO: Add back once we have validated windows.
- # - job: GCNotebookValidation_Ubuntu
+ # - job: GCInfrastructureValidation_Ubuntu
# pool:
# vmImage: ubuntu-latest
# container: ubuntu_x64_build_container
# TODO: Add.
- - job: GCNotebookValidation_Windows
+ - job: GCInfrastructureValidation_Windows
pool:
- vmImage: windows-2019
+ vmImage: windows-2025
steps:
# Install dotnet. We temporarily need both .NET 8 (for building and running the projects) and .NET 9 (for installing deps).
@@ -52,10 +52,17 @@ jobs:
inputs:
version: 10.0.x
includePreviewVersions: true
+ - task: UseDotNet@2
+ displayName: Install .NET 11.0
+ inputs:
+ version: 11.0.x
+ includePreviewVersions: true
- script: dotnet tool restore
- script: dotnet tool install --global dotnet-repl
- - script: dotnet build src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.NotebookTests/GC.Infrastructure.NotebookTests.csproj --configuration Debug --framework net8.0
- - script: dotnet build src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API/GC.Analysis.API.csproj --configuration Release --framework net8.0
+ - script: dotnet build src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/GC.Infrastructure.Core.csproj --configuration Debug --framework net8.0
+ - script: dotnet build src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core.UnitTests/GC.Infrastructure.Core.UnitTests.csproj --configuration Debug --framework net8.0
+ - script: dotnet build src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API/GC.Analysis.API.csproj --configuration Debug --framework net8.0
+ - script: dotnet build src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API.UnitTests/GC.Analysis.API.UnitTests.csproj --configuration Debug --framework net8.0
# Run tests. Template installed from: https://learn.microsoft.com/en-us/azure/devops/pipelines/tasks/reference/vstest-v3?view=azure-pipelines
- task: VSTest@3
@@ -63,16 +70,36 @@ jobs:
# -------------- #
# Test selection #
# -------------- #
- testAssemblyVer2: GC.Infrastructure.NotebookTests.dll
- searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/bin/GC.Infrastructure.NotebookTests/Debug/net8.0'
+ testAssemblyVer2: GC.Infrastructure.Core.UnitTests.dll
+ searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/bin/GC.Infrastructure.Core.UnitTests/Debug/net8.0'
+ otherConsoleOptions: '--Framework:net8.0'
# Uncomment to save results in the future.
# resultsFolder: '$(Agent.TempDirectory)\TestResults' # string. Test results folder. Default: $(Agent.TempDirectory)\TestResults.
# ----------------- #
# Reporting options #
# ----------------- #
- testRunTitle: 'GC Notebook Test'
+ testRunTitle: 'GC Infrastructure Core Unit Test'
# TODO: Double Check.
platform: 'Windows' ## string. Build platform.
# TODO: Double Check.
- configuration: 'Test Notebooks' # string. Build configuration.
\ No newline at end of file
+ configuration: 'Test GC Infrastructure Core' # string. Build configuration.
+ - task: VSTest@3
+ inputs:
+ # -------------- #
+ # Test selection #
+ # -------------- #
+ testAssemblyVer2: GC.Analysis.API.UnitTests.dll
+ searchFolder: '$(System.DefaultWorkingDirectory)/artifacts/bin/GC.Analysis.API.UnitTests/Debug/net8.0'
+ otherConsoleOptions: '--Framework:net8.0'
+ # Uncomment to save results in the future.
+ # resultsFolder: '$(Agent.TempDirectory)\TestResults' # string. Test results folder. Default: $(Agent.TempDirectory)\TestResults.
+
+ # ----------------- #
+ # Reporting options #
+ # ----------------- #
+ testRunTitle: 'GC Analysis API Unit Test'
+ # TODO: Double Check.
+ platform: 'Windows' ## string. Build platform.
+ # TODO: Double Check.
+ configuration: 'Test GC Analysis API' # string. Build configuration.
diff --git a/global.json b/global.json
index 79f2b114c10..148bd94594e 100644
--- a/global.json
+++ b/global.json
@@ -1,15 +1,15 @@
{
"sdk": {
- "version": "11.0.100-preview.3.26170.106",
+ "version": "11.0.100-preview.4.26210.111",
"allowPrerelease": true,
"rollForward": "major"
},
"tools": {
- "dotnet": "11.0.100-preview.3.26170.106"
+ "dotnet": "11.0.100-preview.4.26210.111"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.26210.111",
- "Microsoft.DotNet.Helix.Sdk": "11.0.0-beta.26210.111"
+ "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.26261.101",
+ "Microsoft.DotNet.Helix.Sdk": "11.0.0-beta.26261.101"
},
"native-tools": {
"python3": "3.7.1"
diff --git a/requirements.txt b/requirements.txt
index 41c1983ebf9..4b121a529d9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,9 +1,9 @@
-cryptography==46.0.3
+cryptography==46.0.7
azure.storage.blob==12.13.0
azure.storage.queue==12.4.0
azure.identity==1.16.1
gitpython<=3.1.41
-urllib3==2.6.3
+urllib3==2.7.0
opentelemetry-api==1.23.0
opentelemetry-sdk==1.23.0
six==1.17.0
\ No newline at end of file
diff --git a/scripts/channel_map.py b/scripts/channel_map.py
index 0ca011576d5..118ad072022 100644
--- a/scripts/channel_map.py
+++ b/scripts/channel_map.py
@@ -9,13 +9,11 @@ class ChannelMap():
},
'10.0': {
'tfm': 'net10.0',
- 'branch': '10.0',
- 'quality': 'daily'
+ 'branch': '10.0'
},
'release/10.0': {
'tfm': 'net10.0',
- 'branch': '10.0',
- 'quality': 'daily'
+ 'branch': '10.0'
},
'nativeaot10.0': {
'tfm': 'nativeaot10.0',
diff --git a/scripts/ci_setup.py b/scripts/ci_setup.py
index e622a9fe69b..07c0a95733f 100644
--- a/scripts/ci_setup.py
+++ b/scripts/ci_setup.py
@@ -424,6 +424,11 @@ def main(args: CiSetupArgs):
if args.experiment_name == "jitoptrepeat":
experiment_config = variable_format % ('DOTNET_JitOptRepeat', '*')
+ if args.experiment_name == "runtimeasync":
+ # Surfaced to MSBuild as the $(EnableRuntimeAsync) property; gates the
+ # runtime-async Features flag in src/Directory.Build.targets.
+ experiment_config = variable_format % ('EnableRuntimeAsync', 'true')
+
output = ''
with push_dir(get_repo_root_path()):
diff --git a/scripts/dotnet.py b/scripts/dotnet.py
index 72f006bac80..fc57103c5f1 100755
--- a/scripts/dotnet.py
+++ b/scripts/dotnet.py
@@ -5,6 +5,7 @@
"""
import re
+import json
import datetime
from argparse import ArgumentParser, ArgumentTypeError
from glob import iglob
@@ -862,6 +863,36 @@ def install(
common_cmdline_args += ['-AzureFeed', azure_feed_url]
common_cmdline_args += ['-FeedCredential', internal_build_key]
+ # Shield subsequent `dotnet` invocations (e.g. `dotnet --info` in ci_setup.py)
+ # from picking up an unrelated repo's global.json `paths` entry during the
+ # SDK resolver's upward walk. In particular, dotnet/runtime's global.json
+ # contains a `paths` entry that points the resolver at a `.dotnet` directory
+ # installed by arcade -- which can hold an SDK older than the one the perf
+ # scripts just installed into install_dir. We rewrite the upstream
+ # global.json with the `sdk.paths` field removed, preserving all other
+ # keys (notably `tools.dotnet`, which arcade's bootstrap requires to be
+ # present), letting the perf-installed SDK win via standard `$host$`
+ # resolution while keeping unrelated tooling functional.
+ workspace_root = path.abspath(path.join(get_repo_root_path(), '..'))
+ shield_global_json = path.join(workspace_root, 'global.json')
+ try:
+ if path.exists(shield_global_json):
+ with open(shield_global_json, 'r') as f:
+ shield_data = json.load(f)
+ sdk_section = shield_data.get('sdk')
+ if isinstance(sdk_section, dict) and 'paths' in sdk_section:
+ removed_paths = sdk_section.pop('paths')
+ with open(shield_global_json, 'w') as f:
+ json.dump(shield_data, f, indent=2)
+ f.write('\n')
+ getLogger().info(
+ "Stripped sdk.paths=%s from %s to shield SDK resolver "
+ "from an unrelated repo's global.json",
+ removed_paths, shield_global_json)
+ except (OSError, ValueError) as ex:
+ getLogger().warning(
+ "Could not shield global.json at %s: %s", shield_global_json, ex)
+
# Install Runtime/SDKs
if versions:
for version in versions:
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 96647e856eb..b168fcecc65 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -5,27 +5,27 @@
false
-
+
latest
-
+
False
-
+
$(NoWarn);NU1507
$(NoWarn);NETSDK1138
$(NoWarn);CS9057
True
4
-
+
True
false
false
-
+
false
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
new file mode 100644
index 00000000000..63d3b91f501
--- /dev/null
+++ b/src/Directory.Build.targets
@@ -0,0 +1,11 @@
+
+
+
+
+
+ $(Features);runtime-async=on
+
+
\ No newline at end of file
diff --git a/src/benchmarks/gc/GC.Infrastructure/Configurations/Run.yaml b/src/benchmarks/gc/GC.Infrastructure/Configurations/Run.yaml
index 8dac83d30a2..17be7e9ab35 100644
--- a/src/benchmarks/gc/GC.Infrastructure/Configurations/Run.yaml
+++ b/src/benchmarks/gc/GC.Infrastructure/Configurations/Run.yaml
@@ -12,6 +12,10 @@ coreruns:
environment_variables:
DOTNET_GCName: clrgc.dll
+iterations:
+ gcperfsim: 1
+ microbenchmarks: 1
+
trace_configuration_type: gc # Choose between: none, gc, verbose, cpu, cpu_managed, threadtime, join.
# Optional fields: the contents of both the symbol_path and the source_path will be copied over to the output path.
diff --git a/src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API/Statistics.cs b/src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API/Statistics.cs
index 85c8821a8ec..5f0309b21dd 100644
--- a/src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API/Statistics.cs
+++ b/src/benchmarks/gc/GC.Infrastructure/GC.Analysis.API/Statistics.cs
@@ -31,5 +31,38 @@ public static double StandardDeviation(this IEnumerable doubleList)
double sumOfDerivationAverage = sumOfDerivation / (doubleList.Count() - 1);
return Math.Sqrt(sumOfDerivationAverage - (average * average));
}
+
+ public static IEnumerable RemoveOutliers(IEnumerable collection)
+ {
+ List validCollection = new();
+ if (!collection.Any())
+ {
+ return Array.Empty();
+ }
+ foreach (double value in collection)
+ {
+ if (!double.IsNaN(value) && !double.IsInfinity(value))
+ {
+ validCollection.Add(value);
+ }
+ }
+ if (validCollection.Count == 0)
+ {
+ return Array.Empty();
+ }
+ // Calculate Q1 (25th percentile) and Q3 (75th percentile)
+ double q1 = GC.Analysis.API.Statistics.Percentile(validCollection, 0.25);
+ double q3 = GC.Analysis.API.Statistics.Percentile(validCollection, 0.75);
+
+ // Calculate IQR (Interquartile Range)
+ double iqr = q3 - q1;
+
+ // Calculate bounds: [Q1 - 1.5*IQR, Q3 + 1.5*IQR]
+ double lowerBound = q1 - 1.5 * iqr;
+ double upperBound = q3 + 1.5 * iqr;
+
+ // Filter out outliers
+ return GoodLinq.Where(validCollection, x => x >= lowerBound && x <= upperBound);
+ }
}
}
diff --git a/src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/Analysis/Microbenchmarks/MicrobenchmarkResults.cs b/src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/Analysis/BdnJsonResult.cs
similarity index 53%
rename from src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/Analysis/Microbenchmarks/MicrobenchmarkResults.cs
rename to src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/Analysis/BdnJsonResult.cs
index 2af39abd257..a64f11000a4 100644
--- a/src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/Analysis/Microbenchmarks/MicrobenchmarkResults.cs
+++ b/src/benchmarks/gc/GC.Infrastructure/GC.Infrastructure.Core/Analysis/BdnJsonResult.cs
@@ -1,103 +1,10 @@
-using GC.Analysis.API;
-using GC.Infrastructure.Core.Configurations.Microbenchmarks;
-using GC.Infrastructure.Core.Presentation.GCPerfSim;
-using Newtonsoft.Json;
-
-namespace GC.Infrastructure.Core.Analysis
+namespace GC.Infrastructure.Core.Analysis
{
- public sealed class MicrobenchmarkResult
- {
- public Statistics Statistics { get; set; }
-
- [JsonIgnore]
- public GCProcessData? GCData { get; set; }
-
- public ResultItem ResultItem { get; set; }
-
- [JsonIgnore]
- public CPUProcessData? CPUData { get; set; }
- public Run Parent { get; set; }
- public string MicrobenchmarkName { get; set; }
- public Dictionary OtherMetrics { get; set; } = new();
-
- private static readonly IReadOnlyDictionary> _customStatisticsCalculationMap = new Dictionary>(StringComparer.OrdinalIgnoreCase)
- {
- { "number of iterations", (Statistics stats) => stats.N },
- { "min", (Statistics stats) => stats.Min },
- { "max", (Statistics stats) => stats.Max },
- { "median", (Statistics stats) => stats.Median },
- { "q1", (Statistics stats) => stats.Q1 },
- { "q3", (Statistics stats) => stats.Q3 },
- { "variance", (Statistics stats) => stats.Variance },
- { "standard deviation", (Statistics stats) => stats.StandardDeviation },
- { "skewness", (Statistics stats) => stats.Skewness },
- { "kurtosis", (Statistics stats) => stats.Kurtosis },
- { "standard error", (Statistics stats) => stats.StandardError },
- { "standard error / mean", (Statistics stats) => stats.StandardError / stats.Mean },
- };
-
- public static double? LookupStatisticsCalculation(string columnName, MicrobenchmarkResult result)
- {
- if (string.IsNullOrEmpty(columnName))
- {
- return null;
- }
-
- if (!_customStatisticsCalculationMap.TryGetValue(columnName, out var val))
- {
- return null;
- }
-
- else
- {
- return val.Invoke(result.Statistics);
- }
- }
- }
-
- public sealed class Benchmark
- {
- public string DisplayInfo { get; set; }
- public string Namespace { get; set; }
- public string Type { get; set; }
- public string Method { get; set; }
- public string MethodTitle { get; set; }
- public string Parameters { get; set; }
- public string FullName { get; set; }
- public Statistics Statistics { get; set; }
- public Memory Memory { get; set; }
- public List Measurements { get; set; }
- public List Metrics { get; set; }
- }
-
public sealed class ChronometerFrequency
{
public int Hertz { get; set; }
}
- public sealed class ConfidenceInterval
- {
- public int N { get; set; }
- public double? Mean { get; set; }
- public double? StandardError { get; set; }
- public int? Level { get; set; }
- public double? Margin { get; set; }
- public double? Lower { get; set; }
- public double? Upper { get; set; }
- }
-
- public sealed class Descriptor
- {
- public string Id { get; set; }
- public string DisplayName { get; set; }
- public string Legend { get; set; }
- public string NumberFormat { get; set; }
- public int UnitType { get; set; }
- public string Unit { get; set; }
- public bool TheGreaterTheBetter { get; set; }
- public int PriorityInCategory { get; set; }
- }
-
public sealed class HostEnvironmentInfo
{
public string BenchmarkDotNetCaption { get; set; }
@@ -117,6 +24,16 @@ public sealed class HostEnvironmentInfo
public string HardwareTimerKind { get; set; }
}
+
+ public sealed class Memory
+ {
+ public int Gen0Collections { get; set; }
+ public int Gen1Collections { get; set; }
+ public int Gen2Collections { get; set; }
+ public int TotalOperations { get; set; }
+ public long BytesAllocatedPerOperation { get; set; }
+ }
+
public sealed class Measurement
{
public string IterationMode { get; set; }
@@ -127,19 +44,27 @@ public sealed class Measurement
public long Nanoseconds { get; set; }
}
- public sealed class Memory
+ public sealed class Descriptor
{
- public int Gen0Collections { get; set; }
- public int Gen1Collections { get; set; }
- public int Gen2Collections { get; set; }
- public int TotalOperations { get; set; }
- public long BytesAllocatedPerOperation { get; set; }
+ public string Id { get; set; }
+ public string DisplayName { get; set; }
+ public string Legend { get; set; }
+ public string NumberFormat { get; set; }
+ public int UnitType { get; set; }
+ public string Unit { get; set; }
+ public bool TheGreaterTheBetter { get; set; }
+ public int PriorityInCategory { get; set; }
}
- public sealed class Metric
+ public sealed class ConfidenceInterval
{
- public double Value { get; set; }
- public Descriptor Descriptor { get; set; }
+ public int N { get; set; }
+ public double Mean { get; set; }
+ public double StandardError { get; set; }
+ public int Level { get; set; }
+ public double Margin { get; set; }
+ public double Lower { get; set; }
+ public double Upper { get; set; }
}
public sealed class Percentiles
@@ -155,35 +80,56 @@ public sealed class Percentiles
public double P100 { get; set; }
}
- public sealed class MicrobenchmarkResults
- {
- public string Title { get; set; }
- public HostEnvironmentInfo HostEnvironmentInfo { get; set; }
- public List Benchmarks { get; set; }
- }
-
public sealed class Statistics
{
public List OriginalValues { get; set; }
public int N { get; set; }
- public double? Min { get; set; }
- public double? LowerFence { get; set; }
- public double? Q1 { get; set; }
- public double? Median { get; set; }
- public double? Mean { get; set; }
- public double? Q3 { get; set; }
- public double? UpperFence { get; set; }
- public double? Max { get; set; }
- public double? InterquartileRange { get; set; }
- public List LowerOutliers { get; set; }
+ public double Min { get; set; }
+ public double LowerFence { get; set; }
+ public double Q1 { get; set; }
+ public double Median { get; set; }
+ public double Mean { get; set; }
+ public double Q3 { get; set; }
+ public double UpperFence { get; set; }
+ public double Max { get; set; }
+ public double InterquartileRange { get; set; }
+ public List LowerOutliers { get; set; }
public List