diff --git a/Directory.Packages.props b/Directory.Packages.props
index 233aeb64347..0691b9b3c11 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -13,7 +13,7 @@
-
+
diff --git a/NuGet.config b/NuGet.config
index c25a2dcb1d9..9339987c45f 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -4,7 +4,7 @@
-
+
@@ -21,7 +21,7 @@
-
+
@@ -74,8 +74,4 @@
-
-
-
-
diff --git a/eng/Version.Details.props b/eng/Version.Details.props
index 2bf9a485a9d..18eb4e00bad 100644
--- a/eng/Version.Details.props
+++ b/eng/Version.Details.props
@@ -5,36 +5,36 @@ This file should be imported by eng/Versions.props
-->
-
- 10.0.0-beta.26156.122
- 10.0.0-beta.26156.122
- 10.0.0-beta.26156.122
- 10.0.0-beta.26156.122
- 10.0.0-beta.26156.122
- 10.0.0-beta.26156.122
- 10.0.0-beta.26156.122
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6-servicing.26156.122
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
- 10.0.6
+
+ 10.0.0-beta.26361.102
+ 10.0.0-beta.26361.102
+ 10.0.0-beta.26361.102
+ 10.0.0-beta.26361.102
+ 10.0.0-beta.26361.102
+ 10.0.0-beta.26361.102
+ 10.0.0-beta.26361.102
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10-servicing.26361.102
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
+ 10.0.10
-
+
$(MicrosoftDotNetArcadeSdkPackageVersion)
$(MicrosoftDotNetBuildTasksTemplatingPackageVersion)
$(MicrosoftDotNetCMakeSdkPackageVersion)
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 386bb3815c7..6fda271c464 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -6,110 +6,110 @@ Note: if the Uri is a new place, you will need to add a subscription from that p
And you can check these with "darc get-dependencies target-repo "winforms"
-->
-
+
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
-
+
https://github.com/dotnet/dotnet
- c09352f677332e94b166f59628dd09f50f6afcf2
+ b63fd14d0c0dc26a52814d3f8debb67ba806f1f0
diff --git a/eng/Versions.props b/eng/Versions.props
index 6f47e8b3e52..d1cae567384 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -4,7 +4,7 @@
10
0
- 6
+ 10
servicing
diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml
index 5ce51840619..eaed6d87e65 100644
--- a/eng/common/core-templates/job/job.yml
+++ b/eng/common/core-templates/job/job.yml
@@ -24,12 +24,12 @@ parameters:
enablePublishBuildArtifacts: false
enablePublishBuildAssets: false
enablePublishTestResults: false
+ enablePublishing: false
enableBuildRetry: false
mergeTestResults: false
testRunTitle: ''
testResultsFormat: ''
name: ''
- componentGovernanceSteps: []
preSteps: []
artifactPublishSteps: []
runAsPublic: false
@@ -146,9 +146,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 c5788829a87..eefed3b667a 100644
--- a/eng/common/core-templates/job/onelocbuild.yml
+++ b/eng/common/core-templates/job/onelocbuild.yml
@@ -52,13 +52,13 @@ jobs:
# 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-Windows2022
+ image: 1ESPT-Windows2025
demands: Cmd
os: windows
# If it's not devdiv, it's dnceng
${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
+ image: windows.vs2026.amd64
os: windows
steps:
diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml
index b955fac6e13..06f2eed0323 100644
--- a/eng/common/core-templates/job/publish-build-assets.yml
+++ b/eng/common/core-templates/job/publish-build-assets.yml
@@ -74,13 +74,13 @@ jobs:
# 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-Windows2022
+ image: 1ESPT-Windows2025
demands: Cmd
os: windows
# If it's not devdiv, it's dnceng
${{ if ne(variables['System.TeamProject'], 'DevDiv') }}:
name: NetCore1ESPool-Publishing-Internal
- image: windows.vs2022.amd64
+ image: windows.vs2026.amd64
os: windows
steps:
- ${{ if eq(parameters.is1ESPipeline, '') }}:
@@ -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 }}
- JobLabel: 'Publish_Artifacts_Logs'
+ StageLabel: 'BuildAssetRegistry'
+ JobLabel: 'Publish_Artifacts_Logs'
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/post-build.yml b/eng/common/core-templates/post-build/post-build.yml
index b942a79ef02..905a6315e2d 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
@@ -120,7 +121,7 @@ stages:
# 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-Windows2022
+ image: 1ESPT-Windows2025
demands: Cmd
os: windows
# If it's not devdiv, it's dnceng
@@ -140,16 +141,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
@@ -164,14 +179,14 @@ stages:
# 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-Windows2022
+ image: 1ESPT-Windows2025
demands: Cmd
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
+ image: windows.vs2026.amd64
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
@@ -183,16 +198,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
@@ -225,14 +254,14 @@ stages:
# 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-Windows2022
+ image: 1ESPT-Windows2025
demands: Cmd
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
${{ if eq(parameters.is1ESPipeline, true) }}:
name: $(DncEngInternalBuildPool)
- image: 1es-windows-2022
+ image: windows.vs2026.amd64
os: windows
${{ else }}:
name: $(DncEngInternalBuildPool)
@@ -244,16 +273,30 @@ stages:
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
+ - ${{ if ne(parameters.publishingInfraVersion, 4) }}:
+ - task: DownloadBuildArtifacts@0
+ displayName: Download Blob Artifacts
+ inputs:
+ buildType: specific
+ buildVersionToDownload: specific
+ project: $(AzDOProjectName)
+ pipeline: $(AzDOPipelineId)
+ buildId: $(AzDOBuildId)
+ artifactName: BlobArtifacts
+ checkDownloadedFiles: true
+ - ${{ if eq(parameters.publishingInfraVersion, 4) }}:
+ - task: DownloadPipelineArtifact@2
+ displayName: Download Pipeline Artifacts (V4)
+ inputs:
+ itemPattern: '*/assets/**'
+ targetPath: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+ - task: CopyFiles@2
+ displayName: Flatten assets to BlobArtifacts
+ inputs:
+ SourceFolder: '$(Build.ArtifactStagingDirectory)/PipelineArtifactsDownload'
+ Contents: '**/*'
+ TargetFolder: '$(Build.ArtifactStagingDirectory)/BlobArtifacts'
+ flattenFolders: true
- task: PowerShell@2
displayName: Validate
@@ -286,18 +329,18 @@ stages:
# 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-Windows2022
+ image: 1ESPT-Windows2025
demands: Cmd
os: windows
# If it's not devdiv, it's dnceng
${{ else }}:
${{ if eq(parameters.is1ESPipeline, true) }}:
name: NetCore1ESPool-Publishing-Internal
- image: windows.vs2022.amd64
+ image: windows.vs2026.amd64
os: windows
${{ else }}:
name: NetCore1ESPool-Publishing-Internal
- demands: ImageOverride -equals windows.vs2022.amd64
+ demands: ImageOverride -equals windows.vs2026.amd64
steps:
- template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
parameters:
@@ -328,7 +371,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 c05f6502797..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: 10.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..694f55a926e 100644
--- a/eng/common/core-templates/steps/publish-logs.yml
+++ b/eng/common/core-templates/steps/publish-logs.yml
@@ -33,9 +33,6 @@ steps:
'$(publishing-dnceng-devdiv-code-r-build-re)'
'$(dn-bot-all-orgs-artifact-feeds-rw)'
'$(akams-client-id)'
- '$(microsoft-symbol-server-pat)'
- '$(symweb-symbol-server-pat)'
- '$(dnceng-symbol-server-pat)'
'$(dn-bot-all-orgs-build-rw-code-rw)'
'$(System.AccessToken)'
${{parameters.CustomSensitiveDataList}}
@@ -50,13 +47,14 @@ 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 b9c86c18ae4..09ae5cd73ae 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/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml
index e9a694afa58..6e7666b4dcf 100644
--- a/eng/common/core-templates/steps/source-index-stage1-publish.yml
+++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml
@@ -14,8 +14,8 @@ steps:
workingDirectory: $(Agent.TempDirectory)
- script: |
- $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
- $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
+ $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
displayName: "Source Index: Download netsourceindex Tools"
# Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
workingDirectory: $(Agent.TempDirectory)
diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh
index 8abfb71f727..3150ccac6fc 100755
--- a/eng/common/cross/build-rootfs.sh
+++ b/eng/common/cross/build-rootfs.sh
@@ -5,10 +5,11 @@ set -e
usage()
{
echo "Usage: $0 [BuildArch] [CodeName] [lldbx.y] [llvmx[.y]] [--skipunmount] --rootfsdir ]"
- echo "BuildArch can be: arm(default), arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64, x86"
+ echo "BuildArch can be: arm(default), arm64, loongarch64, ppc64le, riscv64, s390x, x64, x86"
echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine"
echo " for alpine can be specified with version: alpineX.YY or alpineedge"
echo " for FreeBSD can be: freebsd13, freebsd14"
+ echo " for OpenBSD can be: openbsd"
echo " for illumos can be: illumos"
echo " for Haiku can be: haiku."
echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine and FreeBSD"
@@ -27,6 +28,8 @@ __BuildArch=arm
__AlpineArch=armv7
__FreeBSDArch=arm
__FreeBSDMachineArch=armv7
+__OpenBSDArch=arm
+__OpenBSDMachineArch=armv7
__IllumosArch=arm7
__HaikuArch=arm
__QEMUArch=arm
@@ -72,8 +75,8 @@ __AlpinePackages+=" krb5-dev"
__AlpinePackages+=" openssl-dev"
__AlpinePackages+=" zlib-dev"
-__FreeBSDBase="13.4-RELEASE"
-__FreeBSDPkg="1.21.3"
+__FreeBSDBase="13.5-RELEASE"
+__FreeBSDPkg="2.7.5"
__FreeBSDABI="13"
__FreeBSDPackages="libunwind"
__FreeBSDPackages+=" icu"
@@ -82,6 +85,13 @@ __FreeBSDPackages+=" openssl"
__FreeBSDPackages+=" krb5"
__FreeBSDPackages+=" terminfo-db"
+__OpenBSDVersion="7.8"
+__OpenBSDPackages="heimdal-libs"
+__OpenBSDPackages+=" icu4c"
+__OpenBSDPackages+=" libinotify"
+__OpenBSDPackages+=" openssl"
+__OpenBSDPackages+=" e2fsprogs"
+
__IllumosPackages="icu"
__IllumosPackages+=" mit-krb5"
__IllumosPackages+=" openssl"
@@ -130,7 +140,6 @@ __AlpineKeys='
616db30d:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpUpyWDWjlUk3smlWeA0\nlIMW+oJ38t92CRLHH3IqRhyECBRW0d0aRGtq7TY8PmxjjvBZrxTNDpJT6KUk4LRm\na6A6IuAI7QnNK8SJqM0DLzlpygd7GJf8ZL9SoHSH+gFsYF67Cpooz/YDqWrlN7Vw\ntO00s0B+eXy+PCXYU7VSfuWFGK8TGEv6HfGMALLjhqMManyvfp8hz3ubN1rK3c8C\nUS/ilRh1qckdbtPvoDPhSbTDmfU1g/EfRSIEXBrIMLg9ka/XB9PvWRrekrppnQzP\nhP9YE3x/wbFc5QqQWiRCYyQl/rgIMOXvIxhkfe8H5n1Et4VAorkpEAXdsfN8KSVv\nLSMazVlLp9GYq5SUpqYX3KnxdWBgN7BJoZ4sltsTpHQ/34SXWfu3UmyUveWj7wp0\nx9hwsPirVI00EEea9AbP7NM2rAyu6ukcm4m6ATd2DZJIViq2es6m60AE6SMCmrQF\nwmk4H/kdQgeAELVfGOm2VyJ3z69fQuywz7xu27S6zTKi05Qlnohxol4wVb6OB7qG\nLPRtK9ObgzRo/OPumyXqlzAi/Yvyd1ZQk8labZps3e16bQp8+pVPiumWioMFJDWV\nGZjCmyMSU8V6MB6njbgLHoyg2LCukCAeSjbPGGGYhnKLm1AKSoJh3IpZuqcKCk5C\n8CM1S15HxV78s9dFntEqIokCAwEAAQ==
66ba20fe:MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtfB12w4ZgqsXWZDfUAV/\n6Y4aHUKIu3q4SXrNZ7CXF9nXoAVYrS7NAxJdAodsY3vPCN0g5O8DFXR+390LdOuQ\n+HsGKCc1k5tX5ZXld37EZNTNSbR0k+NKhd9h6X3u6wqPOx7SIKxwAQR8qeeFq4pP\nrt9GAGlxtuYgzIIcKJPwE0dZlcBCg+GnptCUZXp/38BP1eYC+xTXSL6Muq1etYfg\nodXdb7Yl+2h1IHuOwo5rjgY5kpY7GcAs8AjGk3lDD/av60OTYccknH0NCVSmPoXK\nvrxDBOn0LQRNBLcAfnTKgHrzy0Q5h4TNkkyTgxkoQw5ObDk9nnabTxql732yy9BY\ns+hM9+dSFO1HKeVXreYSA2n1ndF18YAvAumzgyqzB7I4pMHXq1kC/8bONMJxwSkS\nYm6CoXKyavp7RqGMyeVpRC7tV+blkrrUml0BwNkxE+XnwDRB3xDV6hqgWe0XrifD\nYTfvd9ScZQP83ip0r4IKlq4GMv/R5shcCRJSkSZ6QSGshH40JYSoiwJf5FHbj9ND\n7do0UAqebWo4yNx63j/wb2ULorW3AClv0BCFSdPsIrCStiGdpgJDBR2P2NZOCob3\nG9uMj+wJD6JJg2nWqNJxkANXX37Qf8plgzssrhrgOvB0fjjS7GYhfkfmZTJ0wPOw\nA8+KzFseBh4UFGgue78KwgkCAwEAAQ==
'
-__Keyring=
__KeyringFile="/usr/share/keyrings/ubuntu-archive-keyring.gpg"
__SkipSigCheck=0
__SkipEmulation=0
@@ -153,6 +162,10 @@ while :; do
__AlpineArch=armv7
__QEMUArch=arm
;;
+ armel)
+ # this is only used for tizen-build-rootfs.sh
+ __BuildArch=armel
+ ;;
arm64)
__BuildArch=arm64
__UbuntuArch=arm64
@@ -160,31 +173,8 @@ while :; do
__QEMUArch=aarch64
__FreeBSDArch=arm64
__FreeBSDMachineArch=aarch64
- ;;
- armel)
- __BuildArch=armel
- __UbuntuArch=armel
- __UbuntuRepo="http://archive.debian.org/debian/"
- __CodeName=buster
- __KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
- __LLDB_Package="liblldb-6.0-dev"
- __UbuntuPackages="${__UbuntuPackages// libomp-dev/}"
- __UbuntuPackages="${__UbuntuPackages// libomp5/}"
- __UbuntuSuites=
- ;;
- armv6)
- __BuildArch=armv6
- __UbuntuArch=armhf
- __QEMUArch=arm
- __UbuntuRepo="http://raspbian.raspberrypi.org/raspbian/"
- __CodeName=buster
- __KeyringFile="/usr/share/keyrings/raspbian-archive-keyring.gpg"
- __LLDB_Package="liblldb-6.0-dev"
- __UbuntuSuites=
-
- if [[ -e "$__KeyringFile" ]]; then
- __Keyring="--keyring $__KeyringFile"
- fi
+ __OpenBSDArch=arm64
+ __OpenBSDMachineArch=aarch64
;;
loongarch64)
__BuildArch=loongarch64
@@ -193,10 +183,6 @@ while :; do
__UbuntuArch=loong64
__UbuntuSuites=unreleased
__LLDB_Package="liblldb-19-dev"
-
- if [[ "$__CodeName" == "sid" ]]; then
- __UbuntuRepo="http://ftp.ports.debian.org/debian-ports/"
- fi
;;
riscv64)
__BuildArch=riscv64
@@ -212,7 +198,7 @@ while :; do
__AlpineArch=ppc64le
__QEMUArch=ppc64le
__UbuntuArch=ppc64el
- __UbuntuRepo="http://ports.ubuntu.com/ubuntu-ports/"
+ __UbuntuRepo="https://ports.ubuntu.com/ubuntu-ports/"
__UbuntuPackages="${__UbuntuPackages// libunwind8-dev/}"
__UbuntuPackages="${__UbuntuPackages// libomp-dev/}"
__UbuntuPackages="${__UbuntuPackages// libomp5/}"
@@ -223,7 +209,7 @@ while :; do
__AlpineArch=s390x
__QEMUArch=s390x
__UbuntuArch=s390x
- __UbuntuRepo="http://ports.ubuntu.com/ubuntu-ports/"
+ __UbuntuRepo="https://ports.ubuntu.com/ubuntu-ports/"
__UbuntuPackages="${__UbuntuPackages// libunwind8-dev/}"
__UbuntuPackages="${__UbuntuPackages// libomp-dev/}"
__UbuntuPackages="${__UbuntuPackages// libomp5/}"
@@ -235,15 +221,17 @@ while :; do
__UbuntuArch=amd64
__FreeBSDArch=amd64
__FreeBSDMachineArch=amd64
+ __OpenBSDArch=amd64
+ __OpenBSDMachineArch=amd64
__illumosArch=x86_64
__HaikuArch=x86_64
- __UbuntuRepo="http://archive.ubuntu.com/ubuntu/"
+ __UbuntuRepo="https://archive.ubuntu.com/ubuntu/"
;;
x86)
__BuildArch=x86
__UbuntuArch=i386
__AlpineArch=x86
- __UbuntuRepo="http://archive.ubuntu.com/ubuntu/"
+ __UbuntuRepo="https://archive.ubuntu.com/ubuntu/"
;;
lldb*)
version="$(echo "$lowerI" | tr -d '[:alpha:]-=')"
@@ -295,9 +283,7 @@ while :; do
;;
noble) # Ubuntu 24.04
__CodeName=noble
- if [[ -z "$__LLDB_Package" ]]; then
- __LLDB_Package="liblldb-19-dev"
- fi
+ __LLDB_Package="liblldb-19-dev"
;;
stretch) # Debian 9
__CodeName=stretch
@@ -305,7 +291,7 @@ while :; do
__KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.debian.org/debian/"
+ __UbuntuRepo="https://archive.debian.org/debian/"
fi
;;
buster) # Debian 10
@@ -314,7 +300,7 @@ while :; do
__KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://archive.debian.org/debian/"
+ __UbuntuRepo="https://archive.debian.org/debian/"
fi
;;
bullseye) # Debian 11
@@ -322,7 +308,7 @@ while :; do
__KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.debian.org/debian/"
+ __UbuntuRepo="https://ftp.debian.org/debian/"
fi
;;
bookworm) # Debian 12
@@ -330,7 +316,7 @@ while :; do
__KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.debian.org/debian/"
+ __UbuntuRepo="https://ftp.debian.org/debian/"
fi
;;
sid) # Debian sid
@@ -339,25 +325,21 @@ while :; do
# Debian-Ports architectures need different values
case "$__UbuntuArch" in
- amd64|arm64|armel|armhf|i386|mips64el|ppc64el|riscv64|s390x)
+ amd64|arm64|armhf|i386|mips64el|ppc64el|riscv64|s390x)
__KeyringFile="/usr/share/keyrings/debian-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.debian.org/debian/"
+ __UbuntuRepo="https://ftp.debian.org/debian/"
fi
;;
*)
__KeyringFile="/usr/share/keyrings/debian-ports-archive-keyring.gpg"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ftp.ports.debian.org/debian-ports/"
+ __UbuntuRepo="https://ftp.debian.org/debian-ports/"
fi
;;
esac
-
- if [[ -e "$__KeyringFile" ]]; then
- __Keyring="--keyring $__KeyringFile"
- fi
;;
tizen)
__CodeName=
@@ -383,10 +365,14 @@ while :; do
;;
freebsd14)
__CodeName=freebsd
- __FreeBSDBase="14.2-RELEASE"
+ __FreeBSDBase="14.3-RELEASE"
__FreeBSDABI="14"
__SkipUnmount=1
;;
+ openbsd)
+ __CodeName=openbsd
+ __SkipUnmount=1
+ ;;
illumos)
__CodeName=illumos
__SkipUnmount=1
@@ -457,7 +443,7 @@ fi
__UbuntuPackages+=" ${__LLDB_Package:-}"
if [[ -z "$__UbuntuRepo" ]]; then
- __UbuntuRepo="http://ports.ubuntu.com/"
+ __UbuntuRepo="https://ports.ubuntu.com/"
fi
if [[ -n "$__LLVM_MajorVersion" ]]; then
@@ -544,15 +530,15 @@ if [[ "$__CodeName" == "alpine" ]]; then
# initialize DB
# shellcheck disable=SC2086
"$__ApkToolsDir/apk.static" \
- -X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \
- -X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \
+ -X "https://dl-cdn.alpinelinux.org/alpine/$version/main" \
+ -X "https://dl-cdn.alpinelinux.org/alpine/$version/community" \
-U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" --initdb add
if [[ "$__AlpineLlvmLibsLookup" == 1 ]]; then
# shellcheck disable=SC2086
__AlpinePackages+=" $("$__ApkToolsDir/apk.static" \
- -X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \
- -X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \
+ -X "https://dl-cdn.alpinelinux.org/alpine/$version/main" \
+ -X "https://dl-cdn.alpinelinux.org/alpine/$version/community" \
-U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" \
search 'llvm*-libs' | grep -E '^llvm' | sort | tail -1 | sed 's/-[^-]*//2g')"
fi
@@ -560,8 +546,8 @@ if [[ "$__CodeName" == "alpine" ]]; then
# install all packages in one go
# shellcheck disable=SC2086
"$__ApkToolsDir/apk.static" \
- -X "http://dl-cdn.alpinelinux.org/alpine/$version/main" \
- -X "http://dl-cdn.alpinelinux.org/alpine/$version/community" \
+ -X "https://dl-cdn.alpinelinux.org/alpine/$version/main" \
+ -X "https://dl-cdn.alpinelinux.org/alpine/$version/community" \
-U $__ApkSignatureArg --root "$__RootfsDir" --arch "$__AlpineArch" $__NoEmulationArg \
add $__AlpinePackages
@@ -578,7 +564,7 @@ elif [[ "$__CodeName" == "freebsd" ]]; then
curl -SL "https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz" | tar -C "$__RootfsDir" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version
fi
echo "ABI = \"FreeBSD:${__FreeBSDABI}:${__FreeBSDMachineArch}\"; FINGERPRINTS = \"${__RootfsDir}/usr/share/keys\"; REPOS_DIR = [\"${__RootfsDir}/etc/pkg\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;" > "${__RootfsDir}"/usr/local/etc/pkg.conf
- echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf
+ echo "FreeBSD: { url: \"pkg+https://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf
mkdir -p "$__RootfsDir"/tmp
# get and build package manager
if [[ "$__hasWget" == 1 ]]; then
@@ -592,9 +578,69 @@ elif [[ "$__CodeName" == "freebsd" ]]; then
./autogen.sh && ./configure --prefix="$__RootfsDir"/host && make -j "$JOBS" && make install
rm -rf "$__RootfsDir/tmp/pkg-${__FreeBSDPkg}"
# install packages we need.
- INSTALL_AS_USER=$(whoami) "$__RootfsDir"/host/sbin/pkg -r "$__RootfsDir" -C "$__RootfsDir"/usr/local/etc/pkg.conf update
+ INSTALL_AS_USER=$(whoami) IGNORE_OSVERSION=yes "$__RootfsDir"/host/sbin/pkg -r "$__RootfsDir" -C "$__RootfsDir"/usr/local/etc/pkg.conf update
# shellcheck disable=SC2086
INSTALL_AS_USER=$(whoami) "$__RootfsDir"/host/sbin/pkg -r "$__RootfsDir" -C "$__RootfsDir"/usr/local/etc/pkg.conf install --yes $__FreeBSDPackages
+elif [[ "$__CodeName" == "openbsd" ]]; then
+ # determine mirrors
+ OPENBSD_MIRROR="https://cdn.openbsd.org/pub/OpenBSD/$__OpenBSDVersion/$__OpenBSDMachineArch"
+
+ # download base system sets
+ ensureDownloadTool
+
+ BASE_SETS=(base comp)
+ for set in "${BASE_SETS[@]}"; do
+ FILE="${set}${__OpenBSDVersion//./}.tgz"
+ echo "Downloading $FILE..."
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O- "$OPENBSD_MIRROR/$FILE" | tar -C "$__RootfsDir" -xzpf -
+ else
+ curl -SL "$OPENBSD_MIRROR/$FILE" | tar -C "$__RootfsDir" -xzpf -
+ fi
+ done
+
+ PKG_MIRROR="https://cdn.openbsd.org/pub/OpenBSD/${__OpenBSDVersion}/packages/${__OpenBSDMachineArch}"
+
+ echo "Installing packages into sysroot..."
+
+ # Fetch package index once
+ if [[ "$__hasWget" == 1 ]]; then
+ PKG_INDEX=$(wget -qO- "$PKG_MIRROR/")
+ else
+ PKG_INDEX=$(curl -s "$PKG_MIRROR/")
+ fi
+
+ for pkg in $__OpenBSDPackages; do
+ PKG_FILE=$(echo "$PKG_INDEX" | grep -Po ">\K${pkg}-[0-9][^\" ]*\.tgz" \
+ | sort -V | tail -n1)
+
+ echo "Resolved package filename for $pkg: $PKG_FILE"
+
+ [[ -z "$PKG_FILE" ]] && { echo "ERROR: Package $pkg not found"; exit 1; }
+
+ if [[ "$__hasWget" == 1 ]]; then
+ wget -O- "$PKG_MIRROR/$PKG_FILE" | tar -C "$__RootfsDir/usr/local" -xzpf -
+ else
+ curl -SL "$PKG_MIRROR/$PKG_FILE" | tar -C "$__RootfsDir/usr/local" -xzpf -
+ fi
+ done
+
+ echo "Creating versionless symlinks for shared libraries..."
+ # Find all versioned .so files and create the base .so symlink
+ for lib in "$__RootfsDir"/usr/lib/lib*.so.*; do
+ if [ -f "$lib" ]; then
+ # Extract the filename (e.g., libc++.so.12.0)
+ VERSIONED_NAME=$(basename "$lib")
+ # Remove the trailing version numbers (e.g., libc++.so)
+ BASE_NAME=${VERSIONED_NAME%.so.*}.so
+ # Create the symlink in the same directory
+ ln -sf "$VERSIONED_NAME" "$__RootfsDir/usr/lib/$BASE_NAME"
+ fi
+ done
+
+ echo "Cleaning up unnecessary paths"
+ # we don't use executables and kernel in rootfs (as we use host's compiler with -sysroot)
+ rm -rf "$__RootfsDir/usr/share" "$__RootfsDir/usr/bin"
elif [[ "$__CodeName" == "illumos" ]]; then
mkdir "$__RootfsDir/tmp"
pushd "$__RootfsDir/tmp"
@@ -759,6 +805,14 @@ elif [[ "$__CodeName" == "haiku" ]]; then
elif [[ -n "$__CodeName" ]]; then
__Suites="$__CodeName $(for suite in $__UbuntuSuites; do echo -n "$__CodeName-$suite "; done)"
+ __SigCheckArgs=
+ if [[ "$__SkipSigCheck" == "0" ]]; then
+ if [[ -e "$__KeyringFile" ]]; then
+ __SigCheckArgs="--keyring $__KeyringFile"
+ fi
+ __SigCheckArgs="$__SigCheckArgs --force-check-gpg"
+ fi
+
if [[ "$__SkipEmulation" == "1" ]]; then
if [[ -z "$AR" ]]; then
if command -v ar &>/dev/null; then
@@ -774,31 +828,23 @@ elif [[ -n "$__CodeName" ]]; then
PYTHON=${PYTHON_EXECUTABLE:-python3}
# shellcheck disable=SC2086,SC2046
- echo running "$PYTHON" "$__CrossDir/install-debs.py" --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \
+ echo running "$PYTHON" "$__CrossDir/install-debs.py" $__SigCheckArgs --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \
$(for suite in $__Suites; do echo -n "--suite $suite "; done) \
$__UbuntuPackages
# shellcheck disable=SC2086,SC2046
- "$PYTHON" "$__CrossDir/install-debs.py" --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \
+ "$PYTHON" "$__CrossDir/install-debs.py" $__SigCheckArgs --arch "$__UbuntuArch" --mirror "$__UbuntuRepo" --rootfsdir "$__RootfsDir" --artool "$AR" \
$(for suite in $__Suites; do echo -n "--suite $suite "; done) \
$__UbuntuPackages
exit 0
fi
- __UpdateOptions=
- if [[ "$__SkipSigCheck" == "0" ]]; then
- __Keyring="$__Keyring --force-check-gpg"
- else
- __Keyring=
- __UpdateOptions="--allow-unauthenticated --allow-insecure-repositories"
- fi
-
# shellcheck disable=SC2086
- echo running debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"
+ echo running debootstrap "--variant=minbase" $__SigCheckArgs --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"
# shellcheck disable=SC2086
- if ! debootstrap "--variant=minbase" $__Keyring --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"; then
+ if ! debootstrap "--variant=minbase" $__SigCheckArgs --arch "$__UbuntuArch" "$__CodeName" "$__RootfsDir" "$__UbuntuRepo"; then
echo "debootstrap failed! dumping debootstrap.log"
cat "$__RootfsDir/debootstrap/debootstrap.log"
exit 1
@@ -816,6 +862,11 @@ Components: main universe
Signed-By: $__KeyringFile
EOF
+ __UpdateOptions=
+ if [[ "$__SkipSigCheck" == "1" ]]; then
+ __UpdateOptions="--allow-unauthenticated --allow-insecure-repositories"
+ fi
+
# shellcheck disable=SC2086
chroot "$__RootfsDir" apt-get update $__UpdateOptions
chroot "$__RootfsDir" apt-get -f -y install
diff --git a/eng/common/cross/install-debs.py b/eng/common/cross/install-debs.py
index c81eb37e522..1d1dfabf7dc 100755
--- a/eng/common/cross/install-debs.py
+++ b/eng/common/cross/install-debs.py
@@ -4,6 +4,7 @@
import asyncio
import aiohttp
import gzip
+import hashlib
import os
import re
import shutil
@@ -16,7 +17,7 @@
from collections import deque
from functools import cmp_to_key
-async def download_file(session, url, dest_path, max_retries=3, retry_delay=2, timeout=60):
+async def download_file(session, url, dest_path, max_retries=3, retry_delay=2, timeout=60, checksum=None):
"""Asynchronous file download with retries."""
attempt = 0
while attempt < max_retries:
@@ -25,19 +26,25 @@ async def download_file(session, url, dest_path, max_retries=3, retry_delay=2, t
if response.status == 200:
with open(dest_path, "wb") as f:
content = await response.read()
+
+ # verify checksum if provided
+ if checksum:
+ sha256 = hashlib.sha256(content).hexdigest()
+ if sha256 != checksum:
+ raise Exception(f"SHA256 mismatch for {url}: expected {checksum}, got {sha256}")
+
f.write(content)
print(f"Downloaded {url} at {dest_path}")
return
else:
- print(f"Failed to download {url}, Status Code: {response.status}")
- break
+ raise Exception(f"Failed to download {url}, Status Code: {response.status}")
except (asyncio.CancelledError, asyncio.TimeoutError, aiohttp.ClientError) as e:
print(f"Error downloading {url}: {type(e).__name__} - {e}. Retrying...")
attempt += 1
await asyncio.sleep(retry_delay)
- print(f"Failed to download {url} after {max_retries} attempts.")
+ raise Exception(f"Failed to download {url} after {max_retries} attempts.")
async def download_deb_files_parallel(mirror, packages, tmp_dir):
"""Download .deb files in parallel."""
@@ -51,11 +58,11 @@ async def download_deb_files_parallel(mirror, packages, tmp_dir):
if filename:
url = f"{mirror}/{filename}"
dest_path = os.path.join(tmp_dir, os.path.basename(filename))
- tasks.append(asyncio.create_task(download_file(session, url, dest_path)))
+ tasks.append(asyncio.create_task(download_file(session, url, dest_path, checksum=info.get("SHA256"))))
await asyncio.gather(*tasks)
-async def download_package_index_parallel(mirror, arch, suites):
+async def download_package_index_parallel(mirror, arch, suites, check_sig, keyring):
"""Download package index files for specified suites and components entirely in memory."""
tasks = []
timeout = aiohttp.ClientTimeout(total=60)
@@ -63,10 +70,9 @@ async def download_package_index_parallel(mirror, arch, suites):
async with aiohttp.ClientSession(timeout=timeout) as session:
for suite in suites:
for component in ["main", "universe"]:
- url = f"{mirror}/dists/{suite}/{component}/binary-{arch}/Packages.gz"
- tasks.append(fetch_and_decompress(session, url))
+ tasks.append(fetch_and_decompress(session, mirror, arch, suite, component, check_sig, keyring))
- results = await asyncio.gather(*tasks, return_exceptions=True)
+ results = await asyncio.gather(*tasks)
merged_content = ""
for result in results:
@@ -77,20 +83,75 @@ async def download_package_index_parallel(mirror, arch, suites):
return merged_content
-async def fetch_and_decompress(session, url):
+async def fetch_and_decompress(session, mirror, arch, suite, component, check_sig, keyring):
"""Fetch and decompress the Packages.gz file."""
- try:
- async with session.get(url) as response:
- if response.status == 200:
- compressed_data = await response.read()
- decompressed_data = gzip.decompress(compressed_data).decode('utf-8')
- print(f"Downloaded index: {url}")
- return decompressed_data
- else:
- print(f"Skipped index: {url} (doesn't exist)")
- return None
- except Exception as e:
- print(f"Error fetching {url}: {e}")
+
+ path = f"{component}/binary-{arch}/Packages.gz"
+ url = f"{mirror}/dists/{suite}/{path}"
+
+ async with session.get(url) as response:
+ if response.status == 200:
+ compressed_data = await response.read()
+ decompressed_data = gzip.decompress(compressed_data).decode('utf-8')
+ print(f"Downloaded index: {url}")
+
+ if check_sig:
+ # Verify the package index against the sha256 recorded in the Release file
+ release_file_content = await fetch_release_file(session, mirror, suite, keyring)
+ packages_sha = parse_release_file(release_file_content, path)
+
+ sha256 = hashlib.sha256(compressed_data).hexdigest()
+ if sha256 != packages_sha:
+ raise Exception(f"SHA256 mismatch for {path}: expected {packages_sha}, got {sha256}")
+ print(f"Checksum verified for {path}")
+
+ return decompressed_data
+ else:
+ print(f"Skipped index: {url} (doesn't exist)")
+ return None
+
+async def fetch_release_file(session, mirror, suite, keyring):
+ """Fetch Release and Release.gpg files and verify the signature."""
+
+ release_url = f"{mirror}/dists/{suite}/Release"
+ release_gpg_url = f"{mirror}/dists/{suite}/Release.gpg"
+
+ with tempfile.NamedTemporaryFile() as release_file, tempfile.NamedTemporaryFile() as release_gpg_file:
+ await download_file(session, release_url, release_file.name)
+ await download_file(session, release_gpg_url, release_gpg_file.name)
+
+ print("Verifying signature of Release with Release.gpg.")
+ # Use gpgv rather than gpg for verification. gpgv verifies a detached
+ # signature against a fixed keyring without involving gpg-agent or
+ # keyboxd, which makes it robust on hosts running GnuPG 2.4+ (e.g. Azure
+ # Linux) where "gpg --keyring" routes through keyboxd and can fail.
+ verify_command = ["gpgv"]
+ if keyring:
+ verify_command += ["--keyring", keyring]
+ verify_command += [release_gpg_file.name, release_file.name]
+ result = subprocess.run(verify_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ if result.returncode != 0:
+ raise Exception(f"Signature verification failed: {result.stderr.decode('utf-8')}")
+
+ print("Signature verified successfully.")
+
+ with open(release_file.name) as f:
+ return f.read()
+
+def parse_release_file(content, path):
+ """Parses the Release file and returns sha256 checksum of the specified path."""
+
+ # data looks like this:
+ #
+ matches = re.findall(r'^ (\S*) +(\S*) +(\S*)$', content, re.MULTILINE)
+
+ for entry in matches:
+ # the file has both md5 and sha256 checksums, we want sha256 which has a length of 64
+ if entry[2] == path and len(entry[0]) == 64:
+ return entry[0]
+
+ raise Exception(f"Could not find checksum for {path} in Release file.")
def parse_debian_version(version):
"""Parse a Debian package version into epoch, upstream version, and revision."""
@@ -171,13 +232,15 @@ def parse_package_index(content):
filename = fields.get("Filename")
depends = fields.get("Depends")
provides = fields.get("Provides", None)
+ sha256 = fields.get("SHA256")
# Only update if package_name is not in packages or if the new version is higher
if package_name not in packages or compare_debian_versions(version, packages[package_name]["Version"]) > 0:
packages[package_name] = {
"Version": version,
"Filename": filename,
- "Depends": depends
+ "Depends": depends,
+ "SHA256": sha256
}
# Update aliases if package provides any alternatives
@@ -233,7 +296,7 @@ def extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool):
os.makedirs(extract_dir, exist_ok=True)
with tempfile.TemporaryDirectory(dir=tmp_dir) as tmp_subdir:
- result = subprocess.run(f"{ar_tool} t {os.path.abspath(deb_file)}", cwd=tmp_subdir, check=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ result = subprocess.run([ar_tool, "t", os.path.abspath(deb_file)], cwd=tmp_subdir, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
tar_filename = None
for line in result.stdout.decode().splitlines():
@@ -247,7 +310,8 @@ def extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool):
tar_file_path = os.path.join(tmp_subdir, tar_filename)
print(f"Extracting {tar_filename} from {deb_file}..")
- subprocess.run(f"{ar_tool} p {os.path.abspath(deb_file)} {tar_filename} > {tar_file_path}", check=True, shell=True)
+ with open(tar_file_path, "wb") as outfile:
+ subprocess.run([ar_tool, "p", os.path.abspath(deb_file), tar_filename], check=True, stdout=outfile, stderr=subprocess.PIPE)
file_extension = os.path.splitext(tar_file_path)[1].lower()
@@ -268,7 +332,18 @@ def extract_deb_file(deb_file, tmp_dir, extract_dir, ar_tool):
raise ValueError(f"Unsupported compression format: {file_extension}")
with tarfile.open(tar_file_path, mode) as tar:
- tar.extractall(path=extract_dir, filter='fully_trusted')
+ tar.extractall(path=extract_dir, filter=_rootfs_extraction_filter)
+
+def _rootfs_extraction_filter(member, dest_path):
+ """Tarfile extraction filter based on the 'data' filter that additionally
+ rewrites absolute-target symlinks/hardlinks into rootfs-relative paths.
+ """
+ if (member.issym() or member.islnk()) and os.path.isabs(member.linkname):
+ link_dir = os.path.dirname(member.name)
+ new_linkname = os.path.relpath(member.linkname.lstrip('/'),
+ start=link_dir or '.')
+ member = member.replace(linkname=new_linkname, deep=False)
+ return tarfile.data_filter(member, dest_path)
def finalize_setup(rootfsdir):
lib_dir = os.path.join(rootfsdir, 'lib')
@@ -295,24 +370,17 @@ def finalize_setup(rootfsdir):
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Generate rootfs for .NET runtime on Debian-like OS")
- parser.add_argument("--distro", required=False, help="Distro name (e.g., debian, ubuntu, etc.)")
parser.add_argument("--arch", required=True, help="Architecture (e.g., amd64, loong64, etc.)")
parser.add_argument("--rootfsdir", required=True, help="Destination directory.")
parser.add_argument('--suite', required=True, action='append', help='Specify one or more repository suites to collect index data.')
- parser.add_argument("--mirror", required=False, help="Mirror (e.g., http://ftp.debian.org/debian-ports etc.)")
+ parser.add_argument("--mirror", required=True, help="Mirror (e.g., http://ftp.debian.org/debian-ports etc.)")
parser.add_argument("--artool", required=False, default="ar", help="ar tool to extract debs (e.g., ar, llvm-ar etc.)")
+ parser.add_argument("--force-check-gpg", required=False, action='store_true', help="Verify the packages against signatures in Release file.")
+ parser.add_argument("--keyring", required=False, default='', help="Keyring file to check signature of Release file.")
parser.add_argument("packages", nargs="+", help="List of package names to be installed.")
args = parser.parse_args()
- if args.mirror is None:
- if args.distro == "ubuntu":
- args.mirror = "http://archive.ubuntu.com/ubuntu" if args.arch in ["amd64", "i386"] else "http://ports.ubuntu.com/ubuntu-ports"
- elif args.distro == "debian":
- args.mirror = "http://ftp.debian.org/debian-ports"
- else:
- raise Exception("Unsupported distro")
-
DESIRED_PACKAGES = args.packages + [ # base packages
"dpkg",
"busybox",
@@ -322,9 +390,16 @@ def finalize_setup(rootfsdir):
"debianutils"
]
- print(f"Creating rootfs. rootfsdir: {args.rootfsdir}, distro: {args.distro}, arch: {args.arch}, suites: {args.suite}, mirror: {args.mirror}")
+ print(f"Creating rootfs. rootfsdir: {args.rootfsdir}, arch: {args.arch}, suites: {args.suite}, mirror: {args.mirror}")
+
+ check_sig = args.force_check_gpg
+ if check_sig and not args.keyring:
+ print("ERROR: --force-check-gpg requires --keyring to specify a keyring file for signature verification.")
+ print("Install the appropriate keyring package (e.g., debian-ports-archive-keyring, ubuntu-archive-keyring)")
+ print("or pass --skipsigcheck to build-rootfs.sh to disable signature checking.")
+ sys.exit(1)
- package_index_content = asyncio.run(download_package_index_parallel(args.mirror, args.arch, args.suite))
+ package_index_content = asyncio.run(download_package_index_parallel(args.mirror, args.arch, args.suite, check_sig, args.keyring))
packages_info, aliases = parse_package_index(package_index_content)
diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake
index 0ff85cf0367..f65c689f695 100644
--- a/eng/common/cross/toolchain.cmake
+++ b/eng/common/cross/toolchain.cmake
@@ -3,15 +3,22 @@ set(CROSS_ROOTFS $ENV{ROOTFS_DIR})
# reset platform variables (e.g. cmake 3.25 sets LINUX=1)
unset(LINUX)
unset(FREEBSD)
+unset(OPENBSD)
unset(ILLUMOS)
unset(ANDROID)
unset(TIZEN)
unset(HAIKU)
set(TARGET_ARCH_NAME $ENV{TARGET_BUILD_ARCH})
+
+file(GLOB OPENBSD_PROBE "${CROSS_ROOTFS}/etc/signify/openbsd-*.pub")
+
if(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version)
set(CMAKE_SYSTEM_NAME FreeBSD)
set(FREEBSD 1)
+elseif(OPENBSD_PROBE)
+ set(CMAKE_SYSTEM_NAME OpenBSD)
+ set(OPENBSD 1)
elseif(EXISTS ${CROSS_ROOTFS}/usr/platform/i86pc)
set(CMAKE_SYSTEM_NAME SunOS)
set(ILLUMOS 1)
@@ -52,7 +59,9 @@ elseif(TARGET_ARCH_NAME STREQUAL "arm64")
set(TIZEN_TOOLCHAIN "aarch64-tizen-linux-gnu")
endif()
elseif(FREEBSD)
- set(triple "aarch64-unknown-freebsd12")
+ set(TOOLCHAIN "aarch64-unknown-freebsd14")
+ elseif(OPENBSD)
+ set(TOOLCHAIN "aarch64-unknown-openbsd")
endif()
elseif(TARGET_ARCH_NAME STREQUAL "armel")
set(CMAKE_SYSTEM_PROCESSOR armv7l)
@@ -108,7 +117,9 @@ elseif(TARGET_ARCH_NAME STREQUAL "x64")
set(TIZEN_TOOLCHAIN "x86_64-tizen-linux-gnu")
endif()
elseif(FREEBSD)
- set(triple "x86_64-unknown-freebsd12")
+ set(TOOLCHAIN "x86_64-unknown-freebsd14")
+ elseif(OPENBSD)
+ set(TOOLCHAIN "x86_64-unknown-openbsd")
elseif(ILLUMOS)
set(TOOLCHAIN "x86_64-illumos")
elseif(HAIKU)
@@ -148,9 +159,6 @@ if(TIZEN)
else()
find_toolchain_dir("${CROSS_ROOTFS}/usr/lib64/gcc/${TIZEN_TOOLCHAIN}")
endif()
-
- message(STATUS "TIZEN_TOOLCHAIN_PATH set to: ${TIZEN_TOOLCHAIN_PATH}")
-
include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++)
include_directories(SYSTEM ${TIZEN_TOOLCHAIN_PATH}/include/c++/${TIZEN_TOOLCHAIN})
endif()
@@ -193,11 +201,11 @@ if(ANDROID)
# include official NDK toolchain script
include(${CROSS_ROOTFS}/../build/cmake/android.toolchain.cmake)
-elseif(FREEBSD)
+elseif(FREEBSD OR OPENBSD)
# we cross-compile by instructing clang
- set(CMAKE_C_COMPILER_TARGET ${triple})
- set(CMAKE_CXX_COMPILER_TARGET ${triple})
- set(CMAKE_ASM_COMPILER_TARGET ${triple})
+ set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN})
+ set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN})
+ set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN})
set(CMAKE_SYSROOT "${CROSS_ROOTFS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=lld")
@@ -214,13 +222,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)
@@ -291,7 +305,7 @@ endif()
# Specify compile options
-if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|loongarch64|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT FREEBSD) OR ILLUMOS OR HAIKU)
+if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|loongarch64|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT FREEBSD AND NOT OPENBSD) OR ILLUMOS OR HAIKU)
set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN})
set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN})
set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN})
diff --git a/eng/common/cross/x64/tizen/tizen.patch b/eng/common/cross/x64/tizen/tizen.patch
new file mode 100644
index 00000000000..56fbc881095
--- /dev/null
+++ b/eng/common/cross/x64/tizen/tizen.patch
@@ -0,0 +1,9 @@
+diff -u -r a/usr/lib64/libc.so b/usr/lib64/libc.so
+--- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900
++++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900
+@@ -2,4 +2,4 @@
+ Use the shared library, but some functions are only in
+ the static library, so try that secondarily. */
+ OUTPUT_FORMAT(elf64-x86-64)
+-GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )
++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-x86-64.so.2 ) )
diff --git a/eng/common/cross/x86/tizen/tizen.patch b/eng/common/cross/x86/tizen/tizen.patch
new file mode 100644
index 00000000000..f4fe8838ad6
--- /dev/null
+++ b/eng/common/cross/x86/tizen/tizen.patch
@@ -0,0 +1,9 @@
+diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so
+--- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900
++++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900
+@@ -2,4 +2,4 @@
+ Use the shared library, but some functions are only in
+ the static library, so try that secondarily. */
+ OUTPUT_FORMAT(elf32-i386)
+-GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.2 ) )
++GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.2 ) )
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 e889f439b8d..e6ba4ee28c1 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.ps1 b/eng/common/dotnet.ps1
index 45e5676c9eb..ce4ea40730a 100644
--- a/eng/common/dotnet.ps1
+++ b/eng/common/dotnet.ps1
@@ -8,4 +8,5 @@ $dotnetRoot = InitializeDotNetCli -install:$true
if ($args.count -gt 0) {
$env:DOTNET_NOLOGO=1
& "$dotnetRoot\dotnet.exe" $args
+ ExitWithExitCode $LASTEXITCODE
}
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 100755
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/native/LocateNativeCompiler.targets b/eng/common/native/LocateNativeCompiler.targets
new file mode 100644
index 00000000000..028b33d9444
--- /dev/null
+++ b/eng/common/native/LocateNativeCompiler.targets
@@ -0,0 +1,27 @@
+
+
+
+
+ clang
+ $(ROOTFS_DIR)
+
+
+
+
+
+
+
+ $(_CC_LDFLAGS.SubString(0, $(_CC_LDFLAGS.IndexOf(';'))))
+ <_LDFLAGS>$(_CC_LDFLAGS.SubString($([MSBuild]::Add($(_CC_LDFLAGS.IndexOf(';')), 1))))
+ lld
+
+
+
diff --git a/eng/common/native/NativeAotSupported.props b/eng/common/native/NativeAotSupported.props
new file mode 100644
index 00000000000..559a6663929
--- /dev/null
+++ b/eng/common/native/NativeAotSupported.props
@@ -0,0 +1,26 @@
+
+
+
+
+ <_NativeAotSupportedOS Condition="
+ '$(TargetOS)' != 'browser' and
+ '$(TargetOS)' != 'haiku' and
+ '$(TargetOS)' != 'illumos' and
+ '$(TargetOS)' != 'netbsd' and
+ '$(TargetOS)' != 'solaris'
+ ">true
+
+
+ <_NativeAotSupportedArch Condition="
+ '$(TargetArchitecture)' != 'wasm' and
+ ('$(TargetArchitecture)' != 'x86' or '$(TargetOS)' == 'windows')
+ ">true
+
+ true
+
+
+
diff --git a/eng/common/native/init-distro-rid.sh b/eng/common/native/init-distro-rid.sh
index 83ea7aab0e0..8fc6d2fec78 100644
--- a/eng/common/native/init-distro-rid.sh
+++ b/eng/common/native/init-distro-rid.sh
@@ -39,6 +39,8 @@ getNonPortableDistroRid()
# $rootfsDir can be empty. freebsd-version is a shell script and should always work.
__freebsd_major_version=$("$rootfsDir"/bin/freebsd-version | cut -d'.' -f1)
nonPortableRid="freebsd.$__freebsd_major_version-${targetArch}"
+ elif [ "$targetOs" = "openbsd" ]; then
+ nonPortableRid="openbsd.$(uname -r)-${targetArch}"
elif command -v getprop >/dev/null && getprop ro.product.system.model | grep -qi android; then
__android_sdk_version=$(getprop ro.build.version.sdk)
nonPortableRid="android.$__android_sdk_version-${targetArch}"
diff --git a/eng/common/native/install-dependencies.sh b/eng/common/native/install-dependencies.sh
index 477a44f335b..aff839fa097 100755
--- a/eng/common/native/install-dependencies.sh
+++ b/eng/common/native/install-dependencies.sh
@@ -24,14 +24,16 @@ case "$os" in
apt update
apt install -y build-essential gettext locales cmake llvm clang lld lldb liblldb-dev libunwind8-dev libicu-dev liblttng-ust-dev \
- libssl-dev libkrb5-dev pigz cpio
+ libssl-dev libkrb5-dev pigz cpio ninja-build file
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
- elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then
+ elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ] || [ "$ID" = "centos" ]; then
pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)"
- $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
+ $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio ninja-build file
+ elif [ "$ID" = "amzn" ]; then
+ dnf install -y cmake llvm lld lldb clang python libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio ninja-build file
elif [ "$ID" = "alpine" ]; then
- apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio
+ apk add build-base cmake bash curl clang llvm llvm-dev lld lldb-dev krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio ninja file
else
echo "Unsupported distro. distro: $ID"
exit 1
@@ -52,6 +54,7 @@ brew "openssl@3"
brew "pkgconf"
brew "python3"
brew "pigz"
+brew "ninja"
EOF
;;
diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1
index 472d5bb562c..c1e4104b79a 100644
--- a/eng/common/post-build/redact-logs.ps1
+++ b/eng/common/post-build/redact-logs.ps1
@@ -48,8 +48,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/template-guidance.md b/eng/common/template-guidance.md
index 4bf4cf41bd7..e2b07a865f1 100644
--- a/eng/common/template-guidance.md
+++ b/eng/common/template-guidance.md
@@ -82,7 +82,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)
@@ -107,7 +106,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 92a0664f564..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,18 +38,18 @@ 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: buildArtifacts
+ - output: pipelineArtifact
displayName: Publish Logs
- PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
- publishLocation: Container
- ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
+ 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
@@ -59,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-official/variables/pool-providers.yml b/eng/common/templates-official/variables/pool-providers.yml
index 1f308b24efc..2cc3ae305d5 100644
--- a/eng/common/templates-official/variables/pool-providers.yml
+++ b/eng/common/templates-official/variables/pool-providers.yml
@@ -23,7 +23,7 @@
#
# pool:
# name: $(DncEngInternalBuildPool)
-# image: 1es-windows-2022
+# image: windows.vs2026.amd64
variables:
# Coalesce the target and source branches so we know when a PR targets a release branch
diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml
index 238fa0818f7..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,20 +59,19 @@ 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-build-artifacts.yml
+ - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
parameters:
is1ESPipeline: false
args:
displayName: Publish Logs
- pathToPublish: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
- publishLocation: Container
+ targetPath: '$(Build.ArtifactStagingDirectory)/artifacts/log/$(_BuildConfig)'
artifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)_Attempt$(System.JobAttempt)' ) }}
continueOnError: true
condition: always()
+ 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/templates/steps/vmr-sync.yml b/eng/common/templates/steps/vmr-sync.yml
index eb619c50268..cdc6a28ff1f 100644
--- a/eng/common/templates/steps/vmr-sync.yml
+++ b/eng/common/templates/steps/vmr-sync.yml
@@ -45,11 +45,11 @@ steps:
workingDirectory: ${{ parameters.vmrPath }}
- script: |
- ./eng/common/vmr-sync.sh \
- --vmr ${{ parameters.vmrPath }} \
- --tmp $(Agent.TempDirectory) \
- --azdev-pat '$(dn-bot-all-orgs-code-r)' \
- --ci \
+ ./eng/common/vmr-sync.sh \
+ --vmr ${{ parameters.vmrPath }} \
+ --tmp $(Agent.TempDirectory) \
+ --azdev-pat '$(AzdoToken)' \
+ --ci \
--debug
if [ "$?" -ne 0 ]; then
@@ -67,11 +67,11 @@ steps:
condition: eq(variables['Agent.OS'], 'Windows_NT')
- powershell: |
- ./eng/common/vmr-sync.ps1 `
- -vmr ${{ parameters.vmrPath }} `
- -tmp $(Agent.TempDirectory) `
- -azdevPat '$(dn-bot-all-orgs-code-r)' `
- -ci `
+ ./eng/common/vmr-sync.ps1 `
+ -vmr ${{ parameters.vmrPath }} `
+ -tmp $(Agent.TempDirectory) `
+ -azdevPat '$(AzdoToken)' `
+ -ci `
-debugOutput
if ($LASTEXITCODE -ne 0) {
diff --git a/eng/common/templates/variables/pool-providers.yml b/eng/common/templates/variables/pool-providers.yml
index 18693ea120d..587770f0add 100644
--- a/eng/common/templates/variables/pool-providers.yml
+++ b/eng/common/templates/variables/pool-providers.yml
@@ -23,7 +23,7 @@
#
# pool:
# name: $(DncEngInternalBuildPool)
-# demands: ImageOverride -equals windows.vs2022.amd64
+# demands: ImageOverride -equals windows.vs2026.amd64
variables:
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- template: /eng/common/templates-official/variables/pool-providers.yml
diff --git a/eng/common/templates/vmr-build-pr.yml b/eng/common/templates/vmr-build-pr.yml
index 2f3694fa132..d24de935248 100644
--- a/eng/common/templates/vmr-build-pr.yml
+++ b/eng/common/templates/vmr-build-pr.yml
@@ -33,7 +33,7 @@ resources:
- repository: vmr
type: github
name: dotnet/dotnet
- endpoint: dotnet
+ endpoint: public
ref: refs/heads/main # Set to whatever VMR branch the PR build should insert into
stages:
diff --git a/global.json b/global.json
index d32fc68b66f..efcccdc02d8 100644
--- a/global.json
+++ b/global.json
@@ -1,6 +1,6 @@
{
"sdk": {
- "version": "10.0.103",
+ "version": "10.0.109",
"allowPrerelease": true,
"rollForward": "latestFeature",
"paths": [
@@ -10,7 +10,7 @@
"errorMessage": "The required .NET SDK wasn't found. Please run ./eng/common/dotnet.cmd/sh to install it."
},
"tools": {
- "dotnet": "10.0.103",
+ "dotnet": "10.0.109",
"runtimes": {
"dotnet/x64": [
"$(MicrosoftNETCorePlatformsPackageVersion)"
@@ -21,11 +21,11 @@
}
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26156.122",
- "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.26156.122",
- "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.26156.122",
+ "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26361.102",
+ "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.26361.102",
+ "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.26361.102",
"FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0",
- "Microsoft.NET.Sdk.IL": "10.0.6"
+ "Microsoft.NET.Sdk.IL": "10.0.10"
},
"native-tools": {
"cmake": "latest"
diff --git a/src/System.Private.Windows.Core/src/System/Private/Windows/Ole/Composition.NativeToManagedAdapter.cs b/src/System.Private.Windows.Core/src/System/Private/Windows/Ole/Composition.NativeToManagedAdapter.cs
index 20a48cbaa0d..8c79e1c931d 100644
--- a/src/System.Private.Windows.Core/src/System/Private/Windows/Ole/Composition.NativeToManagedAdapter.cs
+++ b/src/System.Private.Windows.Core/src/System/Private/Windows/Ole/Composition.NativeToManagedAdapter.cs
@@ -104,8 +104,8 @@ private static bool TryGetDataFromHGLOBAL(
object? value = request.Format switch
{
- DataFormatNames.Text or DataFormatNames.Rtf or DataFormatNames.OemText =>
- ReadStringFromHGLOBAL(hglobal, unicode: false),
+ DataFormatNames.Text or DataFormatNames.OemText => ReadStringFromHGLOBAL(hglobal, unicode: false),
+ DataFormatNames.Rtf => ReadRegisteredFormatStringFromHGLOBAL(hglobal, Encoding.Default),
DataFormatNames.Html or DataFormatNames.Xaml => ReadUtf8StringFromHGLOBAL(hglobal),
DataFormatNames.UnicodeText => ReadStringFromHGLOBAL(hglobal, unicode: true),
DataFormatNames.FileDrop => ReadFileListFromHDROP((HDROP)(nint)hglobal),
@@ -181,10 +181,6 @@ private static unsafe string ReadStringFromHGLOBAL(HGLOBAL hglobal, bool unicode
//
// CF_TEXT, CF_OEMTEXT, CF_UNICODETEXT, and CFSTR_FILENAME are supposed to have a null terminator.
// If we cannot find one in the buffer, assume it is corrupted and return an empty string.
- //
- // Can't find the explicit docs for CF_RTF, but we've always treated it as null terminated.
- // The RichText control itself null terminates but looks like it doesn't require it.
- // Given our prior and "normal" behavior, we'll continue to expect a null terminator.
try
{
@@ -226,6 +222,40 @@ private static unsafe string ReadStringFromHGLOBAL(HGLOBAL hglobal, bool unicode
}
}
+ private static unsafe string ReadRegisteredFormatStringFromHGLOBAL(HGLOBAL hglobal, Encoding encoding)
+ {
+ void* buffer = PInvokeCore.GlobalLock(hglobal);
+ if (buffer is null)
+ {
+ throw new Win32Exception();
+ }
+
+ try
+ {
+ int size = checked((int)PInvokeCore.GlobalSize(hglobal));
+ if (size == 0)
+ {
+ throw new Win32Exception();
+ }
+
+ ReadOnlySpan bytes = new((byte*)buffer, size);
+
+ // Registered format strings may be null-terminated, but the terminator is optional.
+ // If present, stop at the first null byte rather than decoding the entire allocation.
+ int nullIndex = bytes.IndexOf((byte)0);
+ if (nullIndex >= 0)
+ {
+ bytes = bytes[..nullIndex];
+ }
+
+ return bytes.IsEmpty ? string.Empty : encoding.GetString(bytes);
+ }
+ finally
+ {
+ PInvokeCore.GlobalUnlock(hglobal);
+ }
+ }
+
private static unsafe string ReadUtf8StringFromHGLOBAL(HGLOBAL hglobal)
{
void* buffer = PInvokeCore.GlobalLock(hglobal);
diff --git a/src/System.Private.Windows.Core/tests/System.Private.Windows.Core.Tests/System/Private/Windows/Ole/NativeToManagedAdapterTests.cs b/src/System.Private.Windows.Core/tests/System.Private.Windows.Core.Tests/System/Private/Windows/Ole/NativeToManagedAdapterTests.cs
index 8f54f54ba82..3818ecc347f 100644
--- a/src/System.Private.Windows.Core/tests/System.Private.Windows.Core.Tests/System/Private/Windows/Ole/NativeToManagedAdapterTests.cs
+++ b/src/System.Private.Windows.Core/tests/System.Private.Windows.Core.Tests/System/Private/Windows/Ole/NativeToManagedAdapterTests.cs
@@ -15,6 +15,7 @@
System.Private.Windows.Nrbf.CoreNrbfSerializer,
System.Private.Windows.Ole.TestFormat>;
using DataFormats = System.Private.Windows.Ole.DataFormatsCore;
+using System.Text;
namespace System.Private.Windows.Ole;
@@ -96,6 +97,19 @@ public void GetData_CustomType_BinaryFormattedData_AsSerializationRecord()
data!.TypeName.AssemblyQualifiedName.Should().Be("System.Int32[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
}
+ [Fact]
+ public void GetData_RtfWithoutNullTerminator_ReturnsRtfText()
+ {
+ const string rtf = "{\\rtf1\\ansi Test}";
+ MemoryStream stream = new(Encoding.Default.GetBytes(rtf));
+ using HGlobalNativeDataObject dataObject = new(stream, (ushort)DataFormats.GetOrAddFormat(DataFormatNames.Rtf).Id);
+
+ var composition = Composition.Create(ComHelpers.GetComPointer(dataObject));
+ object? data = composition.GetData(DataFormatNames.Rtf);
+
+ data.Should().Be(rtf);
+ }
+
[Fact]
public void GetData_CustomType_BinaryFormattedJson_AsSerializationRecord()
{
diff --git a/src/System.Windows.Forms/System/Windows/Forms/Control.cs b/src/System.Windows.Forms/System/Windows/Forms/Control.cs
index 9253cce66ec..7441da6fe06 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/Control.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/Control.cs
@@ -4790,7 +4790,7 @@ protected override void Dispose(bool disposing)
}
// Unsubscribes from the Disposed event of the ContextMenuStrip.
- if (ContextMenuStrip is ContextMenuStrip menu)
+ if (Properties?.TryGetValue(s_contextMenuStripProperty, out ContextMenuStrip? menu) == true)
{
menu.Disposed -= DetachContextMenuStrip;
}
@@ -4816,10 +4816,10 @@ protected override void Dispose(bool disposing)
SuspendLayout();
try
{
- Properties.RemoveValue(s_ncAccessibilityProperty);
+ Properties?.RemoveValue(s_ncAccessibilityProperty);
DisposeAxControls();
- Properties.GetValueOrDefault(s_activeXImplProperty)?.Dispose();
+ Properties?.GetValueOrDefault(s_activeXImplProperty)?.Dispose();
ResetBindings();
diff --git a/src/System.Windows.Forms/System/Windows/Forms/OLE/DataObject.cs b/src/System.Windows.Forms/System/Windows/Forms/OLE/DataObject.cs
index b9205b0ef05..483d939dfd9 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/OLE/DataObject.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/OLE/DataObject.cs
@@ -221,7 +221,8 @@ public virtual StringCollection GetFileDropList()
return dropList;
}
- public virtual Image? GetImage() => GetData(DataFormats.Bitmap, autoConvert: true) as Image;
+ public virtual Image? GetImage() =>
+ TryGetData(DataFormats.Bitmap, autoConvert: true, out Image? image) ? image : null;
public virtual string GetText(TextDataFormat format)
{
diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/DataObjectTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/DataObjectTests.cs
index 3321c4bbf50..1af799f5561 100644
--- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/DataObjectTests.cs
+++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/DataObjectTests.cs
@@ -378,11 +378,29 @@ internal class DataObjectOverridesTryGetDataCore : DataObject
// true is the default value for general purpose APIs (GetData).
private readonly bool _autoConvert;
- public DataObjectOverridesTryGetDataCore(string format, Func? resolver, bool autoConvert) : base()
+ private readonly Type _expectedType;
+ private readonly bool _resultToReturn;
+ private readonly object? _dataToReturn;
+
+ public DataObjectOverridesTryGetDataCore(string format, Func? resolver, bool autoConvert)
+ : this(format, resolver, autoConvert, typeof(string), resultToReturn: false, dataToReturn: null)
+ {
+ }
+
+ public DataObjectOverridesTryGetDataCore(
+ string format,
+ Func? resolver,
+ bool autoConvert,
+ Type expectedType,
+ bool resultToReturn,
+ object? dataToReturn) : base()
{
_format = format;
_resolver = resolver;
_autoConvert = autoConvert;
+ _expectedType = expectedType;
+ _resultToReturn = resultToReturn;
+ _dataToReturn = dataToReturn;
}
public int Count { get; private set; }
@@ -397,9 +415,16 @@ protected override bool TryGetDataCore(
format.Should().Be(_format);
resolver.Should().BeEquivalentTo(_resolver);
autoConvert.Should().Be(_autoConvert);
- typeof(T).Should().Be();
+ typeof(T).Should().Be(_expectedType);
Count++;
+
+ if (typeof(T) == _expectedType && _dataToReturn is not null)
+ {
+ data = (T)_dataToReturn;
+ return _resultToReturn;
+ }
+
// This is a mock implementation that never returns anything.
data = default;
return false;
@@ -909,18 +934,46 @@ public void GetImage_InvokeWithData_ReturnsExpected(object result, Image expecte
[Theory]
[MemberData(nameof(GetImage_TheoryData))]
- public void GetImage_InvokeMocked_ReturnsExpected(object result, Image expected)
+ public void GetImage_Invoke_CallsTryGetData(object result, Image expected)
+ {
+ bool autoConvert = true;
+ bool resultToReturn = result is Image;
+ Image dataToReturn = result as Image;
+ DataObjectOverridesTryGetDataCore dataObject = new(
+ DataFormats.Bitmap,
+ resolver: null,
+ autoConvert,
+ expectedType: typeof(Image),
+ resultToReturn,
+ dataToReturn);
+ dataObject.Count.Should().Be(0);
+
+ Image image = dataObject.GetImage();
+
+ image.Should().BeSameAs(expected);
+ dataObject.Count.Should().Be(1);
+ }
+
+ [WinFormsFact]
+ public void GetDataObject_GetImage_RoundTripsBitmap()
{
- Mock mockDataObject = new(MockBehavior.Strict);
- mockDataObject
- .Setup(o => o.GetImage())
- .CallBase();
- mockDataObject
- .Setup(o => o.GetData(DataFormats.Bitmap, true))
- .Returns(result)
- .Verifiable();
- mockDataObject.Object.GetImage().Should().BeSameAs(expected);
- mockDataObject.Verify(o => o.GetData(DataFormats.Bitmap, true), Times.Once());
+ try
+ {
+ using Bitmap bitmap = new(10, 10);
+ bitmap.SetPixel(1, 2, Color.FromArgb(0x01, 0x02, 0x03, 0x04));
+ Clipboard.SetImage(bitmap);
+
+ DataObject dataObject = Clipboard.GetDataObject().Should().BeOfType().Subject;
+
+ var result = dataObject.GetImage().Should().BeOfType().Subject;
+ result.Size.Should().Be(bitmap.Size);
+ result.GetPixel(1, 2).Should().Be(Color.FromArgb(0xFF, 0xD2, 0xD2, 0xD2));
+ Clipboard.ContainsImage().Should().BeTrue();
+ }
+ finally
+ {
+ Clipboard.Clear();
+ }
}
[Fact]