Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
<RepositoryName>diagnostics</RepositoryName>
</PropertyGroup>

<!-- Inject overrides that must run after the Microsoft.Build.Traversal SDK targets
(e.g. dropping the Test->Build dependency on prebuilt test-only legs). -->
<PropertyGroup>
<CustomAfterTraversalTargets>$(MSBuildThisFileDirectory)eng/TraversalOverrides.targets</CustomAfterTraversalTargets>
</PropertyGroup>

<Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" />

<!--
Expand Down Expand Up @@ -69,10 +75,18 @@
-->
<NetCoreAppMinVersion>8.0</NetCoreAppMinVersion>
<NetCoreAppMinTargetFramework>net$(NetCoreAppMinVersion)</NetCoreAppMinTargetFramework>
<!--
The TFM our unit tests run as. The tools must remain on $(NetCoreAppMinTargetFramework),
but the tests run on the SDK version from global.json, so they can target a newer TFM.
Keeping the tests on the live SDK's TFM means the SDK already ships the matching runtime,
so no extra shared runtime needs to be installed via global.json's tools.runtimes node.
-->
<NetCoreAppTestVersion>10.0</NetCoreAppTestVersion>
<NetCoreAppTestTargetFramework>net$(NetCoreAppTestVersion)</NetCoreAppTestTargetFramework>
Comment thread
hoyosjs marked this conversation as resolved.
<!-- This is the list of TFMs we build our debuggees and tracees as. -->
<SupportedSubProcessTargetFrameworks>net8.0;net9.0;net10.0;net11.0</SupportedSubProcessTargetFrameworks>
<!-- This is the list of TFMs we build our unit tests as. -->
<SupportedXUnitTestTargetFrameworks>net8.0</SupportedXUnitTestTargetFrameworks>
<SupportedXUnitTestTargetFrameworks>$(NetCoreAppTestTargetFramework)</SupportedXUnitTestTargetFrameworks>
</PropertyGroup>

</Project>
65 changes: 56 additions & 9 deletions diagnostics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extends:
parameters:
stages:
- stage: build
displayName: Build and Test Diagnostics
displayName: Build Diagnostics
jobs:

############################
Expand All @@ -79,10 +79,12 @@ extends:
jobTemplate: ${{ variables.jobTemplate }}
name: Windows
osGroup: Windows_NT
buildOnly: ${{ parameters.buildOnly }}
buildOnly: true
publishTestArtifacts: true
buildConfigs:
- configuration: Debug
architecture: x64
artifactUploadPath: bin/Windows_NT.x64.Debug
- configuration: Release
architecture: x64
artifactUploadPath: bin
Expand All @@ -101,6 +103,7 @@ extends:
container: linux_x64
crossBuild: true
buildOnly: true
publishTestArtifacts: true
buildConfigs:
- configuration: Release
architecture: x64
Expand All @@ -119,6 +122,7 @@ extends:
container: linux_musl_x64
crossBuild: true
buildOnly: true
publishTestArtifacts: true
buildConfigs:
- configuration: Release
architecture: x64
Expand All @@ -134,14 +138,16 @@ extends:
parameters:
jobTemplate: ${{ variables.jobTemplate }}
osGroup: MacOS
buildOnly: ${{ parameters.buildOnly }}
buildOnly: true
publishTestArtifacts: true
buildConfigs:
- configuration: Release
architecture: x64
artifactUploadPath: bin/osx.x64.Release
- ${{ if in(variables['Build.Reason'], 'PullRequest') }}:
- configuration: Debug
architecture: x64
artifactUploadPath: bin/osx.x64.Debug

- template: /eng/pipelines/build.yml
parameters:
Expand Down Expand Up @@ -212,13 +218,47 @@ extends:
artifactUploadPath: bin/linux.arm64.Release
artifactTargetPath: bin/linux-musl.arm64.Release

############################
# #
# Test only legs #
# #
############################
############################
# #
# Test stage #
# #
############################

- ${{ if ne(parameters.buildOnly, true) }}:
- stage: test
displayName: Test Diagnostics
dependsOn: build
jobs:

- template: /eng/pipelines/build.yml
parameters:
jobTemplate: ${{ variables.jobTemplate }}
name: Windows_Test
osGroup: Windows_NT
dependsOn: Windows
testOnly: true
buildConfigs:
- configuration: Debug
architecture: x64
- configuration: Release
architecture: x64
- configuration: Release
architecture: x86

- template: /eng/pipelines/build.yml
parameters:
jobTemplate: ${{ variables.jobTemplate }}
name: MacOS_Test
osGroup: MacOS
dependsOn: MacOS
testOnly: true
buildConfigs:
- configuration: Release
architecture: x64
- ${{ if in(variables['Build.Reason'], 'PullRequest') }}:
- configuration: Debug
architecture: x64

- ${{ if ne(parameters.buildOnly, true) }}:
- template: /eng/pipelines/build.yml
parameters:
jobTemplate: ${{ variables.jobTemplate }}
Expand Down Expand Up @@ -267,9 +307,16 @@ extends:
# - configuration: Debug
# architecture: x64

############################
# #
# Package stage #
# #
############################

- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- stage: package
displayName: Package, Sign, and Generate BAR Manifests
dependsOn: build
jobs:
- template: /eng/common/templates-official/job/job.yml
parameters:
Expand Down
2 changes: 1 addition & 1 deletion eng/AuxMsbuildFiles/SdkPackOverrides.targets
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<AspNetVersion11>@(RuntimeTestVersions->WithMetadataValue('TargetFramework', 'net11.0')->Metadata('AspNet'))</AspNetVersion11>
</PropertyGroup>

<Message Importance="High" Text="OverrideTestingVersions: RuntimeTestVersions='@(RuntimeTestVersions)'" />
<Message Importance="Low" Text="OverrideTestingVersions: RuntimeTestVersions=@(RuntimeTestVersions -> '%(Runtime)')" />

<!-- Skip overrides when RuntimeTestVersions is not populated (e.g. test-time CLI builds
where eng/Versions.props is not imported). The SDK's built-in versions are used instead. -->
Expand Down
22 changes: 22 additions & 0 deletions eng/TraversalOverrides.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project>

<!--
Imported via $(CustomAfterTraversalTargets) after the Microsoft.Build.Traversal SDK targets,
so it can override properties the SDK sets unconditionally.

The Traversal SDK hardcodes <TestDependsOn>Build</TestDependsOn>, which makes every traversal's
"Test" target build its entire subgraph (product + tests + their project references) before
running tests, regardless of whether -build was passed. On the test-only CI legs the product and
test binaries are downloaded as prebuilt TestArtifacts, so rebuilding them is pure waste - and
because pipeline artifact downloads do not preserve file timestamps, the up-to-date check fails
and it becomes a full recompile.

Drop the Build dependency when the managed build was skipped ($(SkipTestArtifactsBuild) is set by
build.ps1 / build.sh for -skipmanaged). The traversal "Test" target still invokes "Test" on each
referenced project, so tests run directly against the downloaded binaries with no build.
-->
<PropertyGroup Condition="'$(SkipTestArtifactsBuild)' == 'true'">
<TestDependsOn></TestDependsOn>
</PropertyGroup>

</Project>
24 changes: 24 additions & 0 deletions eng/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,39 @@ if ($test) {
$testFilterArg = "/p:TestRunnerAdditionalArguments=\`"-class $classfilter\`""
}

# When the managed build was skipped (e.g. the test-only CI legs that download prebuilt
# product binaries), the debuggees built by BuildDebuggees in src/tests/dirs.proj were
# downloaded as part of TestArtifacts. Skip rebuilding them so this leg only runs tests.
# Test runtimes are still installed locally below (cheap, ensures correct file permissions).
$skipTestArtifactsBuild = if ($skipmanaged) { 'true' } else { 'false' }

# The managed build normally installs the test SDK/runtimes via an InstallRuntimes.proj
# ProjectReference. The -test step runs with Build=false, so install them explicitly here.
if ($skipmanaged) {
& "$engroot\common\build.ps1" `
-restore -build `
-projects "$engroot\InstallRuntimes.proj" `
-configuration $configuration `
-verbosity $verbosity `
-ci:$ci `
/p:TargetOS=$os `
/p:TargetArch=$architecture
if ($lastExitCode -ne 0) {
exit $lastExitCode
}
}

& "$engroot\common\build.ps1" `
-test `
-restore:$skipmanaged `
-configuration $configuration `
-verbosity $verbosity `
-ci:$ci `
/bl:$logdir\Test.binlog `
/p:TargetOS=$os `
/p:TargetArch=$architecture `
/p:TestArchitectures=$architecture `
/p:SkipTestArtifactsBuild=$skipTestArtifactsBuild `
/p:DotnetRuntimeVersion="$dotnetruntimeversion" `
/p:DotnetRuntimeDownloadVersion="$dotnetruntimedownloadversion" `
/p:RuntimeSourceFeed="$runtimesourcefeed" `
Expand Down
26 changes: 26 additions & 0 deletions eng/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,39 @@ if [[ "$__Test" == 1 ]]; then
__TestFilterArg="/p:TestRunnerAdditionalArguments=\"$__TestFilter\""
fi

# When the managed build was skipped (e.g. the test-only CI legs that download prebuilt
# product binaries), the debuggees built by BuildDebuggees in src/tests/dirs.proj were
# downloaded as part of TestArtifacts. Skip rebuilding them so this leg only runs tests.
# Test runtimes are still installed locally below (cheap, ensures correct file permissions).
__TestRestoreArg=
__SkipTestArtifactsBuild=false
if [[ "$__ManagedBuild" == 0 ]]; then
__TestRestoreArg=--restore
__SkipTestArtifactsBuild=true

# The managed build normally installs the test SDK/runtimes via an InstallRuntimes.proj
# ProjectReference. The --test step runs with Build=false, so install them explicitly here.
"$__RepoRootDir/eng/common/build.sh" \
--restore --build \
--projects "$__RepoRootDir/eng/InstallRuntimes.proj" \
--configuration "$__BuildType" \
/p:TargetArch="$__TargetArch" \
/p:TargetRid="$__TargetRid" \
$__CommonMSBuildArgs
if [ $? != 0 ]; then
exit 1
fi
fi

# __CommonMSBuildArgs contains TargetOS property
"$__RepoRootDir/eng/common/build.sh" \
--test \
$__TestRestoreArg \
--configuration "$__BuildType" \
/bl:"$__LogsDir"/Test.binlog \
/p:TargetArch="$__TargetArch" \
/p:TargetRid="$__TargetRid" \
/p:SkipTestArtifactsBuild="$__SkipTestArtifactsBuild" \
/p:DotnetRuntimeVersion="$__DotnetRuntimeVersion" \
/p:DotnetRuntimeDownloadVersion="$__DotnetRuntimeDownloadVersion" \
/p:RuntimeSourceFeed="$__RuntimeSourceFeed" \
Expand Down
66 changes: 50 additions & 16 deletions eng/pipelines/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ parameters:
type: boolean
default: false

# Optional: publish the full build outputs (managed + native + debuggees) as a
# 'TestArtifacts_<phase>' artifact so the matching test-only legs can run without rebuilding.
- name: publishTestArtifacts
type: boolean
default: false

# Optional: architecture cross build if true
- name: crossBuild
type: boolean
Expand Down Expand Up @@ -113,7 +119,7 @@ jobs:
${{ if ne(parameters.strategy, '') }}:
'error, we can no longer support the strategy feature in the new pipeline system. Please remove the strategy from the job template.': error

${{ if ne(parameters.dependsOn, '') }}:
${{ if and(ne(parameters.dependsOn, ''), ne(parameters.testOnly, true)) }}:
dependsOn: ${{ parameters.dependsOn }}_${{ config.architecture }}_${{ config.configuration }}

workspace:
Expand All @@ -128,16 +134,24 @@ jobs:
- _TestArgs: '-test'
- _Cross: ''

- ${{ if eq(parameters.osGroup, 'Windows_NT') }}:
- _buildScript: $(Build.SourcesDirectory)\build.cmd
- ${{ if ne(parameters.osGroup, 'Windows_NT') }}:
- _buildScript: $(Build.SourcesDirectory)/build.sh

- ${{ if and(eq(parameters.testOnly, 'true'), eq(parameters.buildOnly, 'true')) }}:
'error, testOnly and buildOnly cannot be true at the same time': error

# Test-only legs invoke test.cmd/test.sh, which already encode
# '-test -skipmanaged -skipnative' and do not prepend '-restore -build'. All other legs
# (build-only and build+test) use build.cmd/build.sh, which prepend '-restore -build'.
- ${{ if eq(parameters.testOnly, 'true') }}:
Comment thread
hoyosjs marked this conversation as resolved.
- _TestArgs: '-test -skipnative'
- ${{ if eq(parameters.osGroup, 'Windows_NT') }}:
- _buildScript: $(Build.SourcesDirectory)\test.cmd
- ${{ if ne(parameters.osGroup, 'Windows_NT') }}:
- _buildScript: $(Build.SourcesDirectory)/test.sh
- _TestArgs: ''

- ${{ if ne(parameters.testOnly, 'true') }}:
- ${{ if eq(parameters.osGroup, 'Windows_NT') }}:
- _buildScript: $(Build.SourcesDirectory)\build.cmd
- ${{ if ne(parameters.osGroup, 'Windows_NT') }}:
- _buildScript: $(Build.SourcesDirectory)/build.sh

- ${{ if eq(parameters.buildOnly, 'true') }}:
- _TestArgs: ''
Expand All @@ -157,19 +171,18 @@ jobs:

steps:
- ${{ if eq(parameters.testOnly, true) }}:
- ${{ if ne(parameters.osGroup, 'Linux') }}:
- 'error, testOnly is only supported on Linux': error
- ${{ if notIn(parameters.osGroup, 'Windows_NT', 'MacOS', 'Linux') }}:
- 'error, testOnly is only supported on Windows_NT, MacOS, and Linux': error
# The matching build leg published its full outputs (managed assemblies, native
# binaries, and debuggees) as TestArtifacts_<phase>. Restore them into the repo
# artifacts directory so the test run can skip both the native and managed builds
# (-skipnative -skipmanaged) and only execute the tests.
- task: DownloadPipelineArtifact@2
displayName: 'Download Build Artifacts'
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)/__download__'
itemPattern: Build_${{ parameters.dependsOn }}_${{ config.architecture }}_${{ config.configuration }}/bin/**
artifact: TestArtifacts_${{ parameters.dependsOn }}_${{ config.architecture }}_${{ config.configuration }}
targetPath: '$(Build.SourcesDirectory)/artifacts'
checkDownloadedFiles: true
Comment thread
hoyosjs marked this conversation as resolved.
- task: CopyFiles@2
displayName: 'Binplace Downloaded Product'
inputs:
sourceFolder: $(Build.ArtifactStagingDirectory)/__download__/Build_${{ parameters.dependsOn }}_${{ config.architecture }}_${{ config.configuration }}/bin/linux${{ parameters.osSuffix }}.${{ config.architecture }}.${{ config.configuration }}
targetFolder: '$(Build.SourcesDirectory)/artifacts/bin/linux.${{ config.architecture }}.${{ config.configuration }}'

- script: $(_buildScript)
-ci
Comment thread
hoyosjs marked this conversation as resolved.
Expand Down Expand Up @@ -202,6 +215,27 @@ jobs:
targetPath: '$(Build.ArtifactStagingDirectory)/artifacts'
artifactName: Build_$(_PhaseName)

# Publish the full build outputs for the matching test-only legs to consume. This lets the
# test legs run with -skipnative -skipmanaged instead of rebuilding the product themselves.
# Only valid on build-only legs (publishTestArtifacts without buildOnly is a configuration error).
Comment thread
hoyosjs marked this conversation as resolved.
- ${{ if and(eq(parameters.publishTestArtifacts, true), eq(parameters.buildOnly, true)) }}:
- task: CopyFiles@2
displayName: Gather test artifacts for publish
inputs:
SourceFolder: '$(Build.SourcesDirectory)/artifacts'
Contents: |
bin/**
obj/**
test/**
TargetFolder: $(Build.ArtifactStagingDirectory)/testartifacts

- template: /eng/pipelines/publish-pipeline-artifact-shim.yml@self
parameters:
displayName: Publish Test Artifacts
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)/testartifacts'
artifactName: TestArtifacts_$(_PhaseName)

- ${{ if ne(parameters.buildOnly, 'true') }}:
Comment thread
hoyosjs marked this conversation as resolved.
# Publish test results to Azure Pipelines
- task: PublishTestResults@2
Expand Down
5 changes: 1 addition & 4 deletions global.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,8 @@
"tools": {
"dotnet": "10.0.108",
"runtimes": {
"dotnet": [
"$(MicrosoftNETCoreApp80Version)"
],
"dotnet/x86": [
"$(MicrosoftNETCoreApp80Version)"
"$(MicrosoftNETCoreApp100Version)"
]
}
},
Expand Down
Loading
Loading