Skip to content

Commit be917a9

Browse files
authored
Make SmokeTests use repo infrastructure (#19290)
1 parent f2f907c commit be917a9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+794
-435
lines changed

eng/pipelines/templates/jobs/vmr-build.yml

+24-16
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ jobs:
241241
call $(sourcesPath)\build.cmd -ci -cleanWhileBuilding -prepareMachine /p:TargetOS=${{ parameters.targetOS }} /p:TargetArchitecture=${{ parameters.targetArchitecture }} ${{ parameters.extraProperties }}
242242
displayName: Build
243243
244+
- ${{ if eq(parameters.runTests, 'True') }}:
245+
- script: |
246+
call $(sourcesPath)\build.cmd -ci -prepareMachine -test ${{ parameters.extraProperties }}
247+
displayName: Run Tests
248+
244249
- ${{ else }}:
245250
- ${{ if eq(parameters.buildSourceOnly, 'true') }}:
246251
- script: |
@@ -356,14 +361,13 @@ jobs:
356361
set -ex
357362
358363
dockerVolumeArgs="-v $(sourcesPath):/vmr"
359-
dockerEnvArgs="-e SMOKE_TESTS_EXCLUDE_OMNISHARP=${{ parameters.excludeOmniSharpTests }} -e SMOKE_TESTS_WARN_SDK_CONTENT_DIFFS=true -e SMOKE_TESTS_RUNNING_IN_CI=true"
360364
poisonArg=''
361365
362366
if [[ '${{ parameters.enablePoison }}' == 'True' ]]; then
363367
poisonArg='--poison'
364368
fi
365369
366-
docker run --rm $dockerVolumeArgs -w /vmr $dockerEnvArgs ${{ parameters.container }} ./build.sh --source-only $poisonArg --test $(additionalBuildArgs) /p:SmokeTestConsoleVerbosity=detailed
370+
docker run --rm $dockerVolumeArgs -w /vmr ${{ parameters.container }} ./build.sh /bl:artifacts/log/Release/Test.binlog --source-only --test $poisonArg $(additionalBuildArgs) /p:SmokeTestsWarnOnSdkContentDiffs=true /p:SmokeTestsExcludeOmniSharpTests=${{ parameters.excludeOmniSharpTests }}
367371
displayName: Run Tests
368372
369373
- ${{ if eq(parameters.targetOS, 'windows') }}:
@@ -383,14 +387,14 @@ jobs:
383387
384388
cd "$(sourcesPath)"
385389
386-
CopyWithRelativeFolders "artifacts/" $targetFolder "*.binlog"
387-
CopyWithRelativeFolders "artifacts/" $targetFolder "*.log"
388-
CopyWithRelativeFolders "artifacts/" $targetFolder "*.diff"
390+
CopyWithRelativeFolders "artifacts/log/" $targetFolder "*.binlog"
391+
CopyWithRelativeFolders "artifacts/log/" $targetFolder "*.log"
392+
CopyWithRelativeFolders "artifacts/TestResults/" $targetFolder "*.binlog"
393+
CopyWithRelativeFolders "artifacts/TestResults/" $targetFolder "*.diff"
394+
CopyWithRelativeFolders "artifacts/TestResults/" $targetFolder "Updated*.txt"
395+
CopyWithRelativeFolders "artifacts/TestResults/" $targetFolder "*.trx"
389396
CopyWithRelativeFolders "src/" $targetFolder "*.binlog"
390397
CopyWithRelativeFolders "src/" $targetFolder "*.log"
391-
CopyWithRelativeFolders "test/" $targetFolder "*.binlog"
392-
CopyWithRelativeFolders "test/" $targetFolder "Updated*.diff"
393-
CopyWithRelativeFolders "test/" $targetFolder "Updated*.txt"
394398
395399
# check if we have assets to publish
396400
if (Test-Path "artifacts/assets/Release/*") {
@@ -410,18 +414,20 @@ jobs:
410414
mkdir -p ${targetFolder}
411415
412416
cd "$(sourcesPath)"
413-
find artifacts/ -type f -name "*.binlog" -exec rsync -R {} -t ${targetFolder} \;
414-
find artifacts/ -type f -name "*.log" -exec rsync -R {} -t ${targetFolder} \;
415-
find artifacts/ -type f -name "*.diff" -exec rsync -R {} -t ${targetFolder} \;
417+
find artifacts/log/ -type f -name "*.binlog" -exec rsync -R {} -t ${targetFolder} \;
418+
find artifacts/log/ -type f -name "*.log" -exec rsync -R {} -t ${targetFolder} \;
419+
find artifacts/TestResults/ -type f -name "*.binlog" -exec rsync -R {} -t ${targetFolder} \;
420+
find artifacts/TestResults/ -type f -name "*.diff" -exec rsync -R {} -t ${targetFolder} \;
421+
find artifacts/TestResults/ -type f -name "Updated*.txt" -exec rsync -R {} -t ${targetFolder} \;
422+
find artifacts/TestResults/ -type f -name "*.trx" -exec rsync -R {} -t ${targetFolder} \;
423+
416424
if [[ "${{ parameters.buildSourceOnly }}" == "True" ]]; then
417425
find artifacts/prebuilt-report/ -exec rsync -R {} -t ${targetFolder} \;
418426
find artifacts/log/binary-report/ -exec rsync -R {} -t ${targetFolder} \;
419427
fi
428+
420429
find src/ -type f -name "*.binlog" -exec rsync -R {} -t ${targetFolder} \;
421430
find src/ -type f -name "*.log" -exec rsync -R {} -t ${targetFolder} \;
422-
find test/ -type f -name "*.binlog" -exec rsync -R {} -t ${targetFolder} \;
423-
find test/ -type f -name "Updated*.diff" -exec rsync -R {} -t ${targetFolder} \;
424-
find test/ -type f -name "Updated*.txt" -exec rsync -R {} -t ${targetFolder} \;
425431
426432
# check if we have assets to publish
427433
if [ -n "$(ls -A 'artifacts/assets/Release/')" ]; then
@@ -446,11 +452,11 @@ jobs:
446452
continueOnError: true
447453
inputs:
448454
testRunner: vSTest
449-
testResultsFiles: 'test/**/*.trx'
455+
testResultsFiles: 'artifacts/TestResults/Release/*.trx'
450456
searchFolder: $(sourcesPath)
451457
mergeTestResults: true
452458
publishRunAttachments: true
453-
testRunTitle: SourceBuild_SmokeTests_$(Agent.JobName)
459+
testRunTitle: Tests_$(Agent.JobName)
454460

455461
- task: CopyFiles@2
456462
inputs:
@@ -460,6 +466,7 @@ jobs:
460466
assets/**
461467
TargetFolder: $(Build.ArtifactStagingDirectory)/publishing
462468
displayName: Copy artifacts to Artifact Staging Directory
469+
condition: succeededOrFailed()
463470

464471
# When building from source, the Private.SourceBuilt.Artifacts archive already contains the nuget packages
465472
- ${{ if ne(parameters.buildSourceOnly, 'true') }}:
@@ -468,6 +475,7 @@ jobs:
468475
SourceFolder: $(sourcesPath)/artifacts/packages
469476
TargetFolder: $(Build.ArtifactStagingDirectory)/publishing/packages
470477
displayName: Copy packages to Artifact Staging Directory
478+
condition: succeededOrFailed()
471479

472480
- ${{ if or(ne(variables['System.TeamProject'], 'internal'), eq(variables['Build.Reason'], 'PullRequest')) }}:
473481
- publish: $(Build.ArtifactStagingDirectory)/publishing

src/SourceBuild/content/.gitignore

-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,4 @@
33
/artifacts
44
/prereqs/packages
55
/src/nuget-client/NuGet.config
6-
/test/Microsoft.DotNet.SourceBuild.SmokeTests/bin
7-
/test/Microsoft.DotNet.SourceBuild.SmokeTests/obj
8-
/test/Microsoft.DotNet.SourceBuild.SmokeTests/TestResults
96
*.binlog

src/SourceBuild/content/Directory.Build.props

+8-4
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,18 @@
7373
<TargetRid Condition="'$(ShortStack)' == 'true' and '$(TargetOS)' == 'windows'">win-$(TargetArchitecture)</TargetRid>
7474
</PropertyGroup>
7575

76+
<!-- Set NuGetPackageRoot before Arcade SDK sets it. -->
77+
<PropertyGroup>
78+
<!-- Set RestorePackagesPath so that we don't accidentally pull some packages from the global location. -->
79+
<RestorePackagesPath Condition="'$(RestorePackagesPath)' == ''">$([MSBuild]::NormalizeDirectory('$(MSBuildThisFileDirectory)', '.packages'))</RestorePackagesPath>
80+
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == ''">$(RestorePackagesPath)</NuGetPackageRoot>
81+
</PropertyGroup>
82+
7683
<Import Project="Sdk.props" Sdk="Microsoft.DotNet.Arcade.Sdk" Condition="'$(SkipArcadeSdkImport)' != 'true'" />
7784

7885
<!-- Init basic Arcade props, if the project importing this file doesn't use Arcade.
7986
Keep in sync with props/targets in the Arcade.Sdk. -->
8087
<PropertyGroup Condition="'$(SkipArcadeSdkImport)' == 'true'">
81-
<!-- RepoLayout.props -->
82-
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' != ''">$([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)'))</NuGetPackageRoot>
83-
<NuGetPackageRoot Condition="'$(NuGetPackageRoot)' == '' and '$(NUGET_PACKAGES)' != ''">$([MSBuild]::NormalizeDirectory('$(NUGET_PACKAGES)'))</NuGetPackageRoot>
84-
8588
<RepoRoot Condition="'$(RepoRoot)' == ''">$([MSBuild]::NormalizeDirectory('$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), 'global.json'))'))</RepoRoot>
8689

8790
<!-- Respect environment variable for the .NET install directory if set; otherwise, use the repo default location -->
@@ -212,6 +215,7 @@
212215
<PoisonMarkerFile>.prebuilt.xml</PoisonMarkerFile>
213216
<PoisonReportDataFile>$(PackageReportDir)poison-catalog.xml</PoisonReportDataFile>
214217
<PoisonedReportFile>$(PackageReportDir)poisoned.txt</PoisonedReportFile>
218+
<PoisonUsageReportFile>$(PackageReportDir)poison-usage.xml</PoisonUsageReportFile>
215219
</PropertyGroup>
216220

217221
</Project>

src/SourceBuild/content/Directory.Build.targets

+6-4
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,24 @@
66
<PropertyGroup>
77
<SdkFilenamePrefix>dotnet-sdk-</SdkFilenamePrefix>
88
</PropertyGroup>
9+
910
<ItemGroup>
1011
<SdkTarballItem Include="$(ArtifactsAssetsDir)Sdk/**/$(SdkFilenamePrefix)*$(ArchiveExtension)" />
1112
</ItemGroup>
1213

1314
<!--
1415
Extract SDK version from SDK tarball filename.
16+
Keep in sync with dotnet-sdk's archive location and filename.
1517
1618
Example:
17-
dotnet-sdk-9.0.100-alpha.1.24057.1-fedora.38-x64.tar.gz
18-
dotnet-sdk-<SdkVersion>-<TargetRid><ArchiveExtension>
19+
artifacts\assets\<config>\Sdk\9.0.100-alpha.1.24057.1\dotnet-sdk-9.0.100-alpha.1.24057.1-fedora.38-x64.tar.gz
20+
artifacts\assets\<config>\Sdk\<SdkVersion>\dotnet-sdk-<SdkVersion>-<TargetRid><ArchiveExtension>
1921
-->
2022
<PropertyGroup>
2123
<SdkFilename>%(SdkTarballItem.Filename)%(SdkTarballItem.Extension)</SdkFilename>
22-
<SdkTarballPath>%(SdkTarballItem.Identity)</SdkTarballPath>
24+
<SdkTarballPath Condition="'$(SdkTarballPath)' == ''">%(SdkTarballItem.Identity)</SdkTarballPath>
2325
<SourceBuiltSdkVersion>$(SdkFilename.Replace('$(SdkFilenamePrefix)','').Replace('-$(TargetRid)$(ArchiveExtension)',''))</SourceBuiltSdkVersion>
2426
</PropertyGroup>
2527
</Target>
2628

27-
</Project>
29+
</Project>

src/SourceBuild/content/Directory.Packages.props

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
<PackageVersion Include="Microsoft.Extensions.FileSystemGlobbing" Version="$(MicrosoftExtensionsFileSystemGlobbingVersion)" />
1717
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="$(MicrosoftExtensionsLoggingConsoleVersion)" />
1818
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(MicrosoftExtensionsLoggingVersion)" />
19+
<!-- External dependencies -->
20+
<PackageVersion Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
21+
<PackageVersion Include="xunit.extensibility.core" Version="$(XUnitVersion)" />
22+
<PackageVersion Include="xunit.extensibility.execution" Version="$(XUnitVersion)" />
1923
</ItemGroup>
2024

2125
</Project>

src/SourceBuild/content/build.proj

+10-20
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,24 @@
1-
<Project>
2-
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
1+
<Project Sdk="Microsoft.Build.Traversal">
32

4-
<PropertyGroup>
5-
<!-- Fake, to satisfy the SDK. -->
6-
<TargetFramework>netstandard2.0</TargetFramework>
7-
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
8-
</PropertyGroup>
3+
<ItemGroup>
4+
<ProjectReference Include="$(ToolsDir)init-build.proj" BuildInParallel="false" />
5+
<ProjectReference Include="$(RepoProjectsDir)$(RootRepo).proj" BuildInParallel="false" />
6+
</ItemGroup>
97

10-
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
11-
12-
<Target Name="Build">
8+
<Target Name="PrintInfo" BeforeTargets="Build">
139
<PropertyGroup>
1410
<BuildModeInfoText Condition="'$(DotNetBuildSourceOnly)' == 'true'">source-build</BuildModeInfoText>
1511
<BuildModeInfoText Condition="'$(DotNetBuildSourceOnly)' != 'true'">non-source-build</BuildModeInfoText>
1612
</PropertyGroup>
1713

1814
<Message Text="Build Mode: $(BuildModeInfoText)" Importance="high" />
1915
<Message Text="Build Environment: $(TargetArchitecture) $(Configuration) $(TargetOS) $(TargetRid)" Importance="high" />
20-
21-
<MSBuild Projects="$(ToolsDir)init-build.proj;
22-
$(RepoProjectsDir)$(RootRepo).proj"
23-
Targets="Build"
24-
BuildInParallel="false"
25-
StopOnFirstFailure="true" />
2616
</Target>
2717

2818
<!-- Create a merge manifest from the individual repository manifest files. -->
29-
<UsingTask TaskName="Microsoft.DotNet.UnifiedBuild.Tasks.MergeAssetManifests" AssemblyFile="$(MicrosoftDotNetUnifiedBuildTasksAssembly)" />
19+
<UsingTask TaskName="Microsoft.DotNet.UnifiedBuild.Tasks.MergeAssetManifests" AssemblyFile="$(MicrosoftDotNetUnifiedBuildTasksAssembly)" TaskFactory="TaskHostFactory" />
3020
<Target Name="MergeAssetManifests" AfterTargets="Build">
31-
<PropertyGroup>
21+
<PropertyGroup>
3222
<MergedAssetManifestOutputPath>$(ArtifactsDir)VerticalManifest.xml</MergedAssetManifestOutputPath>
3323
</PropertyGroup>
3424

@@ -48,8 +38,8 @@
4838
<!-- Intentionally below the import to appear at the end. -->
4939
<Target Name="LogBuildOutputFolders"
5040
AfterTargets="Build">
51-
<Message Importance="high" Text="Shipping packages are located in '$(ArtifactsShippingPackagesDir)'." />
52-
<Message Importance="high" Text="Shipping assets are located in '$(ArtifactsAssetsDir)'." />
41+
<Message Importance="high" Text="Shipping packages are located in '$(ArtifactsShippingPackagesDir)'." />
42+
<Message Importance="high" Text="Shipping assets are located in '$(ArtifactsAssetsDir)'." />
5343
</Target>
5444

5545
</Project>

src/SourceBuild/content/build.sh

+30-18
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ usage()
1818
echo "Actions:"
1919
echo " --clean Clean the solution"
2020
echo " --help Print help and exit (short: -h)"
21-
echo " --test Run smoke tests (short: -t)"
21+
echo " --test Run tests (short: -t)"
2222
echo ""
2323

2424
echo "Source-only settings:"
@@ -33,7 +33,7 @@ usage()
3333
echo ""
3434

3535
echo "Advanced settings:"
36-
echo " --build-tests Build repository tests. May not be supported with --source-only"
36+
echo " --build-repo-tests Build repository tests. May not be supported with --source-only"
3737
echo " --ci Set when running on CI server"
3838
echo " --clean-while-building Cleans each repo after building (reduces disk space usage, short: -cwb)"
3939
echo " --excludeCIBinarylog Don't output binary log (short: -nobl)"
@@ -56,10 +56,7 @@ while [[ -h "$source" ]]; do
5656
done
5757
scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
5858

59-
# Set the NUGET_PACKAGES dir so that we don't accidentally pull some packages from the global location,
60-
# They should be pulled from the local feeds.
6159
packagesRestoredDir="$scriptroot/.packages/"
62-
export NUGET_PACKAGES=$packagesRestoredDir/
6360

6461
# Common settings
6562
binary_log=false
@@ -112,8 +109,6 @@ while [[ $# > 0 ]]; do
112109
exit 0
113110
;;
114111
-test|-t)
115-
export NUGET_PACKAGES=$NUGET_PACKAGES/smoke-tests
116-
properties="$properties /t:RunSmokeTest"
117112
test=true
118113
;;
119114

@@ -180,7 +175,6 @@ while [[ $# > 0 ]]; do
180175
-use-mono-runtime)
181176
properties="$properties /p:SourceBuildUseMonoRuntime=true"
182177
;;
183-
184178
*)
185179
properties="$properties $1"
186180
;;
@@ -195,19 +189,37 @@ if [[ "$ci" == true ]]; then
195189
fi
196190
fi
197191

192+
# Never use the global nuget cache folder
193+
use_global_nuget_cache=false
194+
198195
. "$scriptroot/eng/common/tools.sh"
199196

197+
project="$scriptroot/build.proj"
198+
targets="/t:Build"
199+
200+
# This repo uses the VSTest integration instead of the Arcade Test target
201+
if [[ "$test" == true ]]; then
202+
project="$scriptroot/test/tests.proj"
203+
targets="$targets;VSTest"
204+
fi
205+
200206
function Build {
201207
if [[ "$sourceOnly" != "true" ]]; then
202208

203209
InitializeToolset
204210

211+
# Manually unset NUGET_PACKAGES as InitializeToolset sets it unconditionally.
212+
# The env var shouldn't be set so that the RestorePackagesPath msbuild property is respected.
213+
unset NUGET_PACKAGES
214+
205215
local bl=""
206216
if [[ "$binary_log" == true ]]; then
207217
bl="/bl:\"$log_dir/Build.binlog\""
208218
fi
209219

210-
MSBuild "$scriptroot/build.proj" \
220+
MSBuild --restore \
221+
$project \
222+
$targets \
211223
$bl \
212224
/p:Configuration=$configuration \
213225
$properties
@@ -220,22 +232,22 @@ function Build {
220232
properties="$properties /p:ContinuousIntegrationBuild=true"
221233
fi
222234

223-
"$CLI_ROOT/dotnet" build-server shutdown
224-
225-
if [ "$test" == "true" ]; then
226-
"$CLI_ROOT/dotnet" msbuild "$scriptroot/build.proj" -bl:"$scriptroot/artifacts/log/$configuration/BuildTests.binlog" -flp:"LogFile=$scriptroot/artifacts/log/$configuration/BuildTests.log" -clp:v=m $properties
227-
else
235+
if [ "$test" != "true" ]; then
236+
"$CLI_ROOT/dotnet" build-server shutdown
228237
"$CLI_ROOT/dotnet" msbuild "$scriptroot/eng/tools/init-build.proj" -bl:"$scriptroot/artifacts/log/$configuration/BuildMSBuildSdkResolver.binlog" -flp:LogFile="$scriptroot/artifacts/log/$configuration/BuildMSBuildSdkResolver.log" /t:ExtractToolsetPackages,BuildMSBuildSdkResolver $properties
229-
230238
# kill off the MSBuild server so that on future invocations we pick up our custom SDK Resolver
231239
"$CLI_ROOT/dotnet" build-server shutdown
240+
fi
232241

233-
# Point MSBuild to the custom SDK resolvers folder, so it will pick up our custom SDK Resolver
234-
export MSBUILDADDITIONALSDKRESOLVERSFOLDER="$scriptroot/artifacts/toolset/VSSdkResolvers/"
242+
# Point MSBuild to the custom SDK resolvers folder, so it will pick up our custom SDK Resolver
243+
export MSBUILDADDITIONALSDKRESOLVERSFOLDER="$scriptroot/artifacts/toolset/VSSdkResolvers/"
235244

236-
"$CLI_ROOT/dotnet" msbuild "$scriptroot/build.proj" -bl:"$scriptroot/artifacts/log/$configuration/Build.binlog" -flp:"LogFile=$scriptroot/artifacts/log/$configuration/Build.log" $properties
245+
local bl=""
246+
if [[ "$binary_log" == true ]]; then
247+
bl="/bl:\"$log_dir/Build.binlog\""
237248
fi
238249

250+
"$CLI_ROOT/dotnet" msbuild --restore "$project" $bl $targets $properties
239251
fi
240252
}
241253

src/SourceBuild/content/eng/Versions.props

+9-7
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@
2525
-->
2626
<PrivateSourceBuiltSdkVersion>9.0.100-preview.4.24179.1</PrivateSourceBuiltSdkVersion>
2727
<PrivateSourceBuiltArtifactsVersion>9.0.100-preview.4.24179.1</PrivateSourceBuiltArtifactsVersion>
28-
<!-- msbuild -->
29-
<MicrosoftBuildVersion>17.8.3</MicrosoftBuildVersion>
30-
<!-- runtime -->
31-
<MicrosoftExtensionsFileSystemGlobbingVersion>9.0.0-preview.2.24128.5</MicrosoftExtensionsFileSystemGlobbingVersion>
32-
<MicrosoftExtensionsLoggingConsoleVersion>9.0.0-preview.2.24128.5</MicrosoftExtensionsLoggingConsoleVersion>
33-
<MicrosoftExtensionsLoggingVersion>9.0.0-preview.2.24128.5</MicrosoftExtensionsLoggingVersion>
34-
<!-- command-line-api -->
28+
<!-- command-line-api dependencies -->
3529
<SystemCommandLineVersion>2.0.0-beta4.24126.1</SystemCommandLineVersion>
30+
<!-- msbuild dependencies -->
31+
<MicrosoftBuildVersion>17.8.3</MicrosoftBuildVersion>
32+
<!-- runtime dependencies -->
33+
<MicrosoftExtensionsFileSystemGlobbingVersion>8.0.0</MicrosoftExtensionsFileSystemGlobbingVersion>
34+
<MicrosoftExtensionsLoggingConsoleVersion>8.0.0</MicrosoftExtensionsLoggingConsoleVersion>
35+
<MicrosoftExtensionsLoggingVersion>8.0.0</MicrosoftExtensionsLoggingVersion>
36+
<!-- external dependencies -->
37+
<NewtonsoftJsonVersion>13.0.3</NewtonsoftJsonVersion>
3638
</PropertyGroup>
3739
</Project>

0 commit comments

Comments
 (0)