This commit is contained in:
Andrew Arnott 2022-10-30 09:54:53 -06:00
Родитель d996da41a8 cffffa4afb
Коммит 4185a16ecb
49 изменённых файлов: 1106 добавлений и 570 удалений

Просмотреть файл

@ -9,6 +9,10 @@ indent_style = space
# (Please don't specify an indent_size here; that has too many unintended consequences.)
[*.yml]
indent_size = 2
indent_style = space
# Code files
[*.{cs,csx,vb,vbx,h,cpp,idl}]
indent_size = 4
@ -16,16 +20,17 @@ insert_final_newline = true
trim_trailing_whitespace = true
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 4
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,msbuildproj}]
indent_size = 2
# Xml config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct,runsettings}]
indent_size = 2
# JSON files
[*.json]
indent_size = 2
indent_style = space
# Dotnet code style settings:
[*.{cs,vb}]
@ -61,7 +66,7 @@ dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
# Constants are PascalCase
dotnet_naming_rule.constants_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constants_should_be_pascal_case.symbols = constants
dotnet_naming_rule.constants_should_be_pascal_case.style = non_private_static_field_style
dotnet_naming_rule.constants_should_be_pascal_case.style = constant_style
dotnet_naming_symbols.constants.applicable_kinds = field, local
dotnet_naming_symbols.constants.required_modifiers = const
@ -71,7 +76,7 @@ dotnet_naming_style.constant_style.capitalization = pascal_case
# Static fields are camelCase
dotnet_naming_rule.static_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.static_fields_should_be_camel_case.symbols = static_fields
dotnet_naming_rule.static_fields_should_be_camel_case.style = camel_case_style
dotnet_naming_rule.static_fields_should_be_camel_case.style = static_field_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
@ -81,7 +86,7 @@ dotnet_naming_style.static_field_style.capitalization = camel_case
# Instance fields are camelCase
dotnet_naming_rule.instance_fields_should_be_camel_case.severity = suggestion
dotnet_naming_rule.instance_fields_should_be_camel_case.symbols = instance_fields
dotnet_naming_rule.instance_fields_should_be_camel_case.style = camel_case_style
dotnet_naming_rule.instance_fields_should_be_camel_case.style = instance_field_style
dotnet_naming_symbols.instance_fields.applicable_kinds = field
@ -99,7 +104,7 @@ dotnet_naming_style.camel_case_style.capitalization = camel_case
# Local functions are PascalCase
dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions
dotnet_naming_rule.local_functions_should_be_pascal_case.style = non_private_static_field_style
dotnet_naming_rule.local_functions_should_be_pascal_case.style = local_function_style
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
@ -108,28 +113,12 @@ dotnet_naming_style.local_function_style.capitalization = pascal_case
# By default, name items with PascalCase
dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members
dotnet_naming_rule.members_should_be_pascal_case.style = non_private_static_field_style
dotnet_naming_rule.members_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.all_members.applicable_kinds = *
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# SA1629: Documentation text should end with a period
dotnet_diagnostic.SA1629.severity = none
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
end_of_line = crlf
dotnet_style_namespace_match_folder = true:suggestion
# CSharp code style settings:
[*.cs]
# Indentation preferences
@ -140,9 +129,9 @@ csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_for_built_in_types = false
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = false:suggestion
csharp_style_var_elsewhere = false:warning
# Prefer method-like constructs to have a block body
csharp_style_expression_bodied_methods = false:none
@ -166,16 +155,26 @@ csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = tru
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true
# Blocks are allowed
csharp_prefer_braces = true:silent
csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true:suggestion
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_prefer_null_check_over_type_check = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
# SA1130: Use lambda syntax
dotnet_diagnostic.SA1130.severity = silent
# IDE1006: Naming Styles - StyleCop handles these for us
dotnet_diagnostic.IDE1006.severity = none
dotnet_diagnostic.DOC100.severity = silent
dotnet_diagnostic.DOC104.severity = warning
dotnet_diagnostic.DOC105.severity = warning
dotnet_diagnostic.DOC106.severity = warning
dotnet_diagnostic.DOC107.severity = warning
dotnet_diagnostic.DOC108.severity = warning
dotnet_diagnostic.DOC200.severity = warning
dotnet_diagnostic.DOC202.severity = warning
[*.sln]
indent_style = tab

9
.github/dependabot.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,9 @@
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: nuget
directory: /
schedule:
interval: monthly

10
.gitignore поставляемый
Просмотреть файл

@ -9,6 +9,8 @@
*.user
*.userosscache
*.sln.docstates
*.lutconfig
launchSettings.json
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@ -71,6 +73,8 @@ StyleCopReport.xml
*.ipdb
*.pgc
*.pgd
*.rsp
!Directory.Build.rsp
*.sbr
*.tlb
*.tli
@ -79,9 +83,6 @@ StyleCopReport.xml
*.tmp_proj
*_wpftmp.csproj
*.log
msbuild.binlog
*.wrn
*.err
*.vspscc
*.vssscc
.builds
@ -139,6 +140,7 @@ _TeamCity*
# Visual Studio code coverage results
*.coverage
*.coveragexml
/coveragereport/
# NCrunch
_NCrunch_*
@ -329,6 +331,8 @@ ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
*.wrn
*.err
# NVidia Nsight GPU debugger configuration file
*.nvuser

4
.vscode/extensions.json поставляемый
Просмотреть файл

@ -9,7 +9,9 @@
"editorconfig.editorconfig",
"pflannery.vscode-versionlens",
"davidanson.vscode-markdownlint",
"dotjoshjohnson.xml"
"dotjoshjohnson.xml",
"ms-vscode-remote.remote-containers",
"ms-azuretools.vscode-docker"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []

9
.vscode/settings.json поставляемый
Просмотреть файл

@ -1,5 +1,8 @@
{
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"omnisharp.enableEditorConfigSupport": true,
"omnisharp.enableImportCompletion": true,
"omnisharp.enableRoslynAnalyzers": true
}

158
Directory.Build.props Normal file
Просмотреть файл

@ -0,0 +1,158 @@
<Project>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<RepoRootPath>$(MSBuildThisFileDirectory)</RepoRootPath>
<BaseIntermediateOutputPath>$(RepoRootPath)obj\$([MSBuild]::MakeRelative($(RepoRootPath), $(MSBuildProjectDirectory)))\</BaseIntermediateOutputPath>
<BaseOutputPath Condition=" '$(BaseOutputPath)' == '' ">$(RepoRootPath)bin\$(MSBuildProjectName)\</BaseOutputPath>
<PackageOutputPath>$(RepoRootPath)bin\Packages\$(Configuration)\</PackageOutputPath>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<AnalysisLevel>latest</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ProduceReferenceAssembly Condition=" '$(IsTestProject)' != 'true' ">true</ProduceReferenceAssembly>
<IsTestProject>$(MSBuildProjectName.Contains('Test'))</IsTestProject>
<IsCodeGenerationProject Condition=" $(MSBuildProjectName.Contains('CodeGeneration')) ">true</IsCodeGenerationProject>
<IsPInvokeProject Condition=" '$(IsTestProject)' != 'true' and '$(IsCodeGenerationProject)' != 'true' ">true</IsPInvokeProject>
<IsPackable Condition=" '$(IsTestProject)' == 'true' or '$(IsCodeGenerationProject)' == 'true' ">false</IsPackable>
<!-- https://github.com/dotnet/msbuild/blob/main/documentation/ProjectReference-Protocol.md#setplatform-negotiation -->
<EnableDynamicPlatformResolution>true</EnableDynamicPlatformResolution>
<!-- Opt in till https://github.com/NuGet/Home/issues/9803 makes this the default. -->
<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>
<!-- This entire repo has just one version.json file, so compute the version once and share with all projects in a large build. -->
<GitVersionBaseDirectory>$(MSBuildThisFileDirectory)</GitVersionBaseDirectory>
<!-- Local builds should embed PDBs so we never lose them when a subsequent build occurs. -->
<DebugType Condition=" '$(CI)' != 'true' and '$(TF_BUILD)' != 'true' ">embedded</DebugType>
<NoWarn>$(NoWarn);CS1591;CA1401</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)strongname.snk</AssemblyOriginatorKeyFile>
<DesktopOnlyFrameworks>net45</DesktopOnlyFrameworks>
<PlatformSpecificFrameworks>$(DesktopOnlyFrameworks);uap10.0.19041</PlatformSpecificFrameworks>
<PortableOnlyFrameworks>netstandard2.0</PortableOnlyFrameworks>
<PlatformAndPortableFrameworks>$(PortableOnlyFrameworks);$(PlatformSpecificFrameworks)</PlatformAndPortableFrameworks>
<TargetPlatformMinVersion Condition=" '$(TargetFramework)' == 'win8' ">8.0</TargetPlatformMinVersion>
<Title>PInvoke.$(MSBuildProjectName)</Title>
<Authors>Andrew Arnott</Authors>
<Summary>P/Invoke methods for the Windows $(MSBuildProjectName).dll.</Summary>
<Description>P/Invoke methods for the Windows $(MSBuildProjectName).dll.</Description>
<PackageProjectUrl>https://github.com/dotnet/pinvoke</PackageProjectUrl>
<Copyright>Copyright © .NET Foundation and Contributors</Copyright>
<Tags>pinvoke .net pcl</Tags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols Condition=" '$(DebugType)' != 'embedded' ">true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.119" PrivateAssets="all" />
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all" />
<!-- Use the Unstable package ID so that update tools will help us keep it current even though it seems to be ever-unstable lately. -->
<PackageReference Include="StyleCop.Analyzers.Unstable" Version="1.2.0.435" PrivateAssets="all" />
<PackageReference Include="CSharpIsNullAnalyzer" Version="0.1.329" PrivateAssets="all" />
<PackageReference Include="DotNetAnalyzers.DocumentationAnalyzers" Version="1.0.0-beta.59" PrivateAssets="all" />
</ItemGroup>
<ItemGroup Condition=" '$(IsCodeGenerationProject)' != 'true' ">
<ProjectReference Include="..\CodeGenerationAttributes\CodeGenerationAttributes.csproj" PrivateAssets="all">
<Private>false</Private>
<OutputItemType>Analyzer</OutputItemType>
</ProjectReference>
<ProjectReference Include="..\CodeGeneration\CodeGeneration.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Analyzer</OutputItemType>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
<UndefineProperties>TargetFramework</UndefineProperties>
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup Condition=" '$(IsTestProject)' == 'true' ">
<PackageReference Include="coverlet.msbuild" Version="3.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit.runner.console" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="$(MSBuildThisFileDirectory)stylecop.json" Link="stylecop.json" />
</ItemGroup>
<PropertyGroup Condition=" '$(IsCodeGenerationProject)' != 'true' ">
<RootNamespace>PInvoke</RootNamespace>
<AssemblyName>PInvoke.$(MSBuildProjectName)</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(IsTestProject)' == 'true' ">
<OutputPath>$(RepoRootPath)bin\$(Configuration)\tests\$(MSBuildProjectName)\</OutputPath>
<RootNamespace />
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)PInvoke.Tests.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup>
<!-- We build all libraries to a common directory, so avoid trying to copy P2P refs to the directory
to avoid wasting time with file collisions and build warnings. -->
<ProjectReference Condition=" '$(IsTestProject)' != 'true' ">
<!-- Sadly, enabling this optimization breaks loading the assembly later for exporting p/invoke method coverage. -->
<!-- <Private>false</Private> -->
</ProjectReference>
</ItemDefinitionGroup>
<ItemGroup>
<GeneratorAssemblySearchPaths Include="$(RepoRootPath)bin\$(Configuration)\netstandard2.0\" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)../stylecop.json"/>
<None Include="$(MSBuildProjectName).exports.txt" Condition=" Exists('$(MSBuildProjectName).exports.txt') and '$(TargetFramework)' == 'net45' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemDefinitionGroup>
<!-- We always want MSBuild properties generated that point at the restored location of each package. -->
<PackageReference GeneratePathProperty="true" />
</ItemDefinitionGroup>
<Target Name="PrepareReleaseNotes" BeforeTargets="GenerateNuspec" DependsOnTargets="GetBuildVersion">
<PropertyGroup>
<PackageReleaseNotes>https://github.com/dotnet/pinvoke/releases/tag/v$(Version)</PackageReleaseNotes>
</PropertyGroup>
</Target>
<PropertyGroup Condition="'$(IsWpfTempProject)' == ''">
<IsWpfTempProject>false</IsWpfTempProject>
<IsWpfTempProject Condition="$(MSBuildProjectName.EndsWith('_wpftmp'))">true</IsWpfTempProject>
</PropertyGroup>
<!--
Inspired by https://github.com/dotnet/arcade/blob/cbfa29d4e859622ada3d226f90f103f659665d31/src/Microsoft.DotNet.Arcade.Sdk/tools/Workarounds.props#L14-L31
WPF temp-projects do not import .props and .targets files from NuGet packages.
(see https://github.com/dotnet/sourcelink/issues/91).
Property _TargetAssemblyProjectName is set by GenerateTemporaryTargetAssembly task.
Disable Source Link and Xliff in WPF temp projects to avoid generating non-deterministic file names to obj dir.
The project name is non-deterministic and is included in the Source Link json file name and xlf directory names.
It's also not necessary to generate these assets.
-->
<PropertyGroup Condition="'$(IsWpfTempProject)' == 'true'">
<_WpfTempProjectNuGetFilePathNoExt>$(BaseIntermediateOutputPath)..\$(_TargetAssemblyProjectName)\$(_TargetAssemblyProjectName)$(MSBuildProjectExtension).nuget.g</_WpfTempProjectNuGetFilePathNoExt>
<EnableSourceLink>false</EnableSourceLink>
<EmbedUntrackedSources>false</EmbedUntrackedSources>
<DeterministicSourcePaths>false</DeterministicSourcePaths>
<EnableXlfLocalization>false</EnableXlfLocalization>
</PropertyGroup>
<!-- Workaround https://github.com/dotnet/wpf/issues/810 -->
<Import Project="$(_WpfTempProjectNuGetFilePathNoExt).props" Condition="'$(_WpfTempProjectNuGetFilePathNoExt)' != '' and Exists('$(_WpfTempProjectNuGetFilePathNoExt).props')"/>
</Project>

37
Directory.Build.targets Normal file
Просмотреть файл

@ -0,0 +1,37 @@
<Project>
<PropertyGroup>
<!-- Workaround https://github.com/dotnet/wpf/issues/1718 -->
<EmbedUntrackedSources Condition=" '$(UseWPF)' == 'true' ">false</EmbedUntrackedSources>
</PropertyGroup>
<PropertyGroup>
<RootNamespace Condition=" '$(IsTestProject)' == 'true' " />
<ExcludeStoreBannedAPIs Condition=" ('$(TargetPlatformIdentifier)' == 'Windows' or '$(TargetPlatformIdentifier)' == 'UAP') and '$(TargetPlatformVersion)' >= 8.0 ">true</ExcludeStoreBannedAPIs>
<DefineConstants Condition=" '$(ExcludeStoreBannedAPIs)' != 'true' ">$(DefineConstants);IncludeStoreBannedAPIs</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' or ('$(TargetFrameworkIdentifier)' == '.NETStandard' and '$(_TargetFrameworkVersionWithoutV)' >= 2.0) ">$(DefineConstants);Serialization</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' == '.NETStandard' and '$(_TargetFrameworkVersionWithoutV)' >= 2.0 ">$(DefineConstants);NETSTANDARD2_0_ORLATER</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(_TargetFrameworkVersionWithoutV)' >= 4.5 ">$(DefineConstants);NET45_ORLATER</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' != '.NETFramework' ">$(DefineConstants);APISets</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Remove="storebanned\**" Condition=" '$(ExcludeStoreBannedAPIs)' == 'true' " />
<Compile Remove="**" Condition=" '$(ExcludeStoreBannedAPIs)' == 'true' and '$(StoreBanned)' == 'true' " />
<Compile Include="$(MSBuildThisFileDirectory)AssemblyAttributes.cs" Condition=" '$(IsPInvokeProject)' == 'true' " />
<Compile Include="$(MSBuildThisFileDirectory)AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(IsPInvokeProject)' == 'true' and '$(MSBuildProjectName)' != 'Win32' and '$(TargetFramework)' == 'net45' ">
<PackageReference Include="Roslyn.Diagnostics.Analyzers" Version="1.2.0-beta2" PrivateAssets="all" />
<AdditionalFiles Include="PublicAPI.Shipped.txt" />
<AdditionalFiles Include="PublicAPI.Unshipped.txt" />
</ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)PInvoke.Extra.targets" Condition=" '$(IsTestProject)' != 'true' and '$(IsCodeGenerationProject)' != 'true' "/>
<!-- Workaround win8 .targets defining a target that should be blank (https://github.com/dotnet/sdk/issues/2517) -->
<Target Name="GetPackagingOutputs" />
<Import Project="$(_WpfTempProjectNuGetFilePathNoExt).targets" Condition="'$(_WpfTempProjectNuGetFilePathNoExt)' != '' and Exists('$(_WpfTempProjectNuGetFilePathNoExt).targets')"/>
</Project>

Просмотреть файл

@ -9,18 +9,24 @@ trigger:
- doc/
- '*.md'
- .vscode/
- .github/
- azure-pipelines/release.yml
stages:
- stage: Build
variables:
TreatWarningsAsErrors: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
BuildConfiguration: Release
BuildPlatform: Any CPU
codecov_token: e300ab17-4cd6-43b5-8292-e824cb320ed3
ci_feed: OSS/PublicCI
NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages
GeneratePInvokesTxt: true
jobs:
- template: azure-pipelines/build.yml
parameters:
- name: RunTests
displayName: Run tests
type: boolean
default: true
variables:
TreatWarningsAsErrors: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
BuildConfiguration: Release
codecov_token: 4dc9e7e2-6b01-4932-a180-847b52b43d35 # Get a new one from https://codecov.io/
ci_feed: https://pkgs.dev.azure.com/andrewarnott/OSS/_packaging/PublicCI/nuget/v3/index.json
NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages/
jobs:
- template: azure-pipelines/build.yml
parameters:
RunTests: ${{ parameters.RunTests }}

Просмотреть файл

@ -0,0 +1,15 @@
Param(
[switch]$CleanIfLocal
)
if ($env:BUILD_ARTIFACTSTAGINGDIRECTORY) {
$ArtifactStagingFolder = $env:BUILD_ARTIFACTSTAGINGDIRECTORY
} elseif ($env:RUNNER_TEMP) {
$ArtifactStagingFolder = "$env:RUNNER_TEMP\_artifacts"
} else {
$ArtifactStagingFolder = [System.IO.Path]::GetFullPath("$PSScriptRoot/../obj/_artifacts")
if ($CleanIfLocal -and (Test-Path $ArtifactStagingFolder)) {
Remove-Item $ArtifactStagingFolder -Recurse -Force
}
}
$ArtifactStagingFolder

Просмотреть файл

@ -0,0 +1,86 @@
<#
.SYNOPSIS
Downloads the CodeCov.io uploader tool and returns the path to it.
.PARAMETER AllowSkipVerify
Allows skipping signature verification of the downloaded tool if gpg is not installed.
#>
[CmdletBinding()]
Param(
[switch]$AllowSkipVerify
)
if ($IsMacOS) {
$codeCovUrl = "https://uploader.codecov.io/latest/macos/codecov"
$toolName = 'codecov'
}
elseif ($IsLinux) {
$codeCovUrl = "https://uploader.codecov.io/latest/linux/codecov"
$toolName = 'codecov'
}
else {
$codeCovUrl = "https://uploader.codecov.io/latest/windows/codecov.exe"
$toolName = 'codecov.exe'
}
$shaSuffix = ".SHA256SUM"
$sigSuffix = $shaSuffix + ".sig"
Function Get-FileFromWeb([Uri]$Uri, $OutDir) {
$OutFile = Join-Path $OutDir $Uri.Segments[-1]
if (!(Test-Path $OutFile)) {
Write-Verbose "Downloading $Uri..."
if (!(Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null }
try {
(New-Object System.Net.WebClient).DownloadFile($Uri, $OutFile)
} finally {
# This try/finally causes the script to abort
}
}
$OutFile
}
$toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1"
$binaryToolsPath = Join-Path $toolsPath codecov
$testingPath = Join-Path $binaryToolsPath unverified
$finalToolPath = Join-Path $binaryToolsPath $toolName
if (!(Test-Path $finalToolPath)) {
if (Test-Path $testingPath) {
Remove-Item -Recurse -Force $testingPath # ensure we download all matching files
}
$tool = Get-FileFromWeb $codeCovUrl $testingPath
$sha = Get-FileFromWeb "$codeCovUrl$shaSuffix" $testingPath
$sig = Get-FileFromWeb "$codeCovUrl$sigSuffix" $testingPath
$key = Get-FileFromWeb https://keybase.io/codecovsecurity/pgp_keys.asc $testingPath
if ((Get-Command gpg -ErrorAction SilentlyContinue)) {
Write-Host "Importing codecov key" -ForegroundColor Yellow
gpg --import $key
Write-Host "Verifying signature on codecov hash" -ForegroundColor Yellow
gpg --verify $sig $sha
} else {
if ($AllowSkipVerify) {
Write-Warning "gpg not found. Unable to verify hash signature."
} else {
throw "gpg not found. Unable to verify hash signature. Install gpg or add -AllowSkipVerify to override."
}
}
Write-Host "Verifying hash on downloaded tool" -ForegroundColor Yellow
$actualHash = (Get-FileHash -Path $tool -Algorithm SHA256).Hash
$expectedHash = (Get-Content $sha).Split()[0]
if ($actualHash -ne $expectedHash) {
# Validation failed. Delete the tool so we can't execute it.
#Remove-Item $codeCovPath
throw "codecov uploader tool failed signature validation."
}
Copy-Item $tool $finalToolPath
if ($IsMacOS -or $IsLinux) {
chmod u+x $finalToolPath
}
}
return $finalToolPath

Просмотреть файл

@ -1,10 +1,10 @@
<#
.SYNOPSIS
Collect the list of PDBs built in this repo, after converting them from portable to Windows PDBs.
Collect the list of PDBs built in this repo.
.PARAMETER Path
The root path to recursively search for PDBs.
The directory to recursively search for PDBs.
.PARAMETER Tests
A switch indicating to find test-related PDBs instead of product-only PDBs.
A switch indicating to find PDBs only for test binaries instead of only for shipping shipping binaries.
#>
[CmdletBinding()]
param (
@ -13,19 +13,12 @@ param (
[switch]$Tests
)
$WindowsPdbSubDirName = "symstore"
$ActivityName = "Collecting symbols from $Path"
Write-Progress -Activity $ActivityName -CurrentOperation "Discovery PDB files"
$PDBs = Get-ChildItem -rec "$Path/*.pdb" |? { $_.FullName -notmatch "\W$WindowsPdbSubDirName\W" }
$PDBs = Get-ChildItem -rec "$Path/*.pdb"
# Filter PDBs to product OR test related.
$testregex = "unittest|tests"
if ($Tests) {
$PDBs = $PDBs |? { $_.FullName -match $testregex }
} else {
$PDBs = $PDBs |? { $_.FullName -notmatch $testregex }
}
$testregex = "unittest|tests|\.test\."
Write-Progress -Activity $ActivityName -CurrentOperation "De-duplicating symbols"
$PDBsByHash = @{}
@ -42,6 +35,12 @@ $PDBs |% {
$PDBsByHash.Add($_.Hash, $_.FullName)
Write-Output $_
}
} |? {
if ($Tests) {
$_.FullName -match $testregex
} else {
$_.FullName -notmatch $testregex
}
} |% {
# Collect the DLLs/EXEs as well.
$dllPath = "$($_.Directory)/$($_.BaseName).dll"
@ -50,8 +49,13 @@ $PDBs |% {
$BinaryImagePath = $dllPath
} elseif (Test-Path $exePath) {
$BinaryImagePath = $exePath
} else {
Write-Warning "`"$_`" found with no matching binary file."
$BinaryImagePath = $null
}
Write-Output $BinaryImagePath
Write-Output $_
if ($BinaryImagePath) {
Write-Output $BinaryImagePath
Write-Output $_.FullName
}
}

Просмотреть файл

@ -0,0 +1,51 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Merges code coverage reports.
.PARAMETER Path
The path(s) to search for Cobertura code coverage reports.
.PARAMETER Format
The format for the merged result. The default is Cobertura
.PARAMETER OutputDir
The directory the merged result will be written to. The default is `coveragereport` in the root of this repo.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[string[]]$Path,
[ValidateSet('Badges', 'Clover', 'Cobertura', 'CsvSummary', 'Html', 'Html_Dark', 'Html_Light', 'HtmlChart', 'HtmlInline', 'HtmlInline_AzurePipelines', 'HtmlInline_AzurePipelines_Dark', 'HtmlInline_AzurePipelines_Light', 'HtmlSummary', 'JsonSummary', 'Latex', 'LatexSummary', 'lcov', 'MarkdownSummary', 'MHtml', 'PngChart', 'SonarQube', 'TeamCitySummary', 'TextSummary', 'Xml', 'XmlSummary')]
[string]$Format='Cobertura',
[string]$OutputFile=("$PSScriptRoot/../coveragereport/merged.cobertura.xml")
)
$RepoRoot = [string](Resolve-Path $PSScriptRoot/..)
if (!(Test-Path $RepoRoot/obj/dotnet-coverage*)) {
dotnet tool install --tool-path $RepoRoot/obj dotnet-coverage --version 17.4.3 --configfile $PSScriptRoot/justnugetorg.nuget.config
}
Write-Verbose "Searching $Path for *.cobertura.xml files"
$reports = Get-ChildItem -Recurse $Path -Filter *.cobertura.xml
if ($reports) {
$reports |% { $_.FullName } |% {
# In addition to replacing {reporoot}, we also normalize on one kind of slash so that the report aggregates data for a file whether data was collected on Windows or not.
$xml = [xml](Get-Content -Path $_)
$xml.coverage.packages.package.classes.class |? { $_.filename} |% {
$_.filename = $_.filename.Replace('{reporoot}', $RepoRoot).Replace([IO.Path]::AltDirectorySeparatorChar, [IO.Path]::DirectorySeparatorChar)
}
$xml.Save($_)
}
$Inputs = $reports |% { Resolve-Path -relative $_.FullName }
if (Split-Path $OutputFile) {
New-Item -Type Directory -Path (Split-Path $OutputFile) | Out-Null
}
& "$RepoRoot/obj/dotnet-coverage" merge $Inputs -o $OutputFile -f cobertura
} else {
Write-Error "No reports found to merge."
}

Просмотреть файл

@ -1,12 +0,0 @@
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="blame" enabled="True">
<Configuration>
<CollectDump DumpType="full" />
<CollectDumpOnTestSessionHang TestTimeout="30000" DumpType="full" />
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>

Просмотреть файл

@ -2,13 +2,13 @@
# It "snaps" the values of these variables where we can compute them during the build,
# and otherwise captures the scripts to run later during an Azure Pipelines environment release.
$RepoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot (Join-Path .. ..)))
$ArtifactBasePath = Join-Path $RepoRoot (Join-Path obj _artifacts)
$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot/../..")
$ArtifactBasePath = "$RepoRoot/obj/_artifacts"
$VariablesArtifactPath = Join-Path $ArtifactBasePath variables
if (-not (Test-Path $VariablesArtifactPath)) { New-Item -ItemType Directory -Path $VariablesArtifactPath | Out-Null }
# Copy variables, either by value if the value is calculable now, or by script
Get-ChildItem -Path (Join-Path $PSScriptRoot (Join-Path .. variables)) |% {
Get-ChildItem "$PSScriptRoot/../variables" |% {
$value = $null
if (-not $_.BaseName.StartsWith('_')) { # Skip trying to interpret special scripts
# First check the environment variables in case the variable was set in a queued build
@ -35,7 +35,7 @@ Get-ChildItem -Path (Join-Path $PSScriptRoot (Join-Path .. variables)) |% {
$value = Get-Content -Path $_.FullName
}
Set-Content -Path (Join-Path $VariablesArtifactPath $_.Name) -Value $value
Set-Content -Path "$VariablesArtifactPath/$($_.Name)" -Value $value
}
@{

Просмотреть файл

@ -12,9 +12,10 @@
Value = an array of paths (absolute or relative to the BaseDirectory) to files to include in the artifact.
FileInfo objects are also allowed.
.PARAMETER Force
Executes artifact scripts even if they have already been uploaded.
Executes artifact scripts even if they have already been staged.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param (
[string]$ArtifactNameSuffix,
[switch]$Force
@ -28,14 +29,14 @@ Function EnsureTrailingSlash($path) {
$path.Replace('\', [IO.Path]::DirectorySeparatorChar)
}
Function Test-ArtifactUploaded($artifactName) {
$varName = "ARTIFACTUPLOADED_$($artifactName.ToUpper())"
Function Test-ArtifactStaged($artifactName) {
$varName = "ARTIFACTSTAGED_$($artifactName.ToUpper())"
Test-Path "env:$varName"
}
Get-ChildItem "$PSScriptRoot\*.ps1" -Exclude "_*" -Recurse | % {
$ArtifactName = $_.BaseName
if ($Force -or !(Test-ArtifactUploaded($ArtifactName + $ArtifactNameSuffix))) {
if ($Force -or !(Test-ArtifactStaged($ArtifactName + $ArtifactNameSuffix))) {
$totalFileCount = 0
$fileGroups = & $_
if ($fileGroups) {
@ -65,6 +66,6 @@ Get-ChildItem "$PSScriptRoot\*.ps1" -Exclude "_*" -Recurse | % {
Write-Warning "No files found for the `"$ArtifactName`" artifact."
}
} else {
Write-Host "Skipping $ArtifactName because it has already been uploaded." -ForegroundColor DarkGray
Write-Host "Skipping $ArtifactName because it has already been staged." -ForegroundColor DarkGray
}
}

Просмотреть файл

@ -1,15 +1,44 @@
# This script translates all the artifacts described by _all.ps1
# into commands that instruct Azure Pipelines to actually collect those artifacts.
<#
.SYNOPSIS
This script translates all the artifacts described by _all.ps1
into commands that instruct Azure Pipelines to actually collect those artifacts.
#>
[CmdletBinding()]
param (
[string]$ArtifactNameSuffix
[string]$ArtifactNameSuffix,
[switch]$StageOnly
)
& "$PSScriptRoot/_stage_all.ps1" -ArtifactNameSuffix $ArtifactNameSuffix |% {
Write-Host "##vso[artifact.upload containerfolder=$($_.Name);artifactname=$($_.Name);]$($_.Path)"
Function Set-PipelineVariable($name, $value) {
if ((Test-Path "Env:\$name") -and (Get-Item "Env:\$name").Value -eq $value) {
return # already set
}
#New-Item -Path "Env:\$name".ToUpper() -Value $value -Force | Out-Null
Write-Host "##vso[task.setvariable variable=$name]$value"
}
Function Test-ArtifactUploaded($artifactName) {
$varName = "ARTIFACTUPLOADED_$($artifactName.ToUpper())"
Test-Path "env:$varName"
}
& "$PSScriptRoot/_stage_all.ps1" -ArtifactNameSuffix $ArtifactNameSuffix |% {
# Set a variable which will out-live this script so that a subsequent attempt to collect and upload artifacts
# will skip this one from a check in the _all.ps1 script.
$varName = "ARTIFACTUPLOADED_$($_.Name.ToUpper())"
Write-Host "##vso[task.setvariable variable=$varName]true"
Set-PipelineVariable "ARTIFACTSTAGED_$($_.Name.ToUpper())" 'true'
Write-Host "Staged artifact $($_.Name) to $($_.Path)"
if (!$StageOnly) {
if (Test-ArtifactUploaded $_.Name) {
Write-Host "Skipping $($_.Name) because it has already been uploaded." -ForegroundColor DarkGray
} else {
Write-Host "##vso[artifact.upload containerfolder=$($_.Name);artifactname=$($_.Name);]$($_.Path)"
# Set a variable which will out-live this script so that a subsequent attempt to collect and upload artifacts
# will skip this one from a check in the _all.ps1 script.
Set-PipelineVariable "ARTIFACTUPLOADED_$($_.Name.ToUpper())" 'true'
}
}
}

Просмотреть файл

@ -1,20 +1,16 @@
# This script links all the artifacts described by _all.ps1
# into a staging directory, reading for uploading to a cloud build artifact store.
# It returns a sequence of objects with Name and Path properties.
<#
.SYNOPSIS
This script links all the artifacts described by _all.ps1
into a staging directory, reading for uploading to a cloud build artifact store.
It returns a sequence of objects with Name and Path properties.
#>
[CmdletBinding()]
param (
[string]$ArtifactNameSuffix
)
$RepoRoot = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot (Join-Path .. ..)))
if ($env:BUILD_ARTIFACTSTAGINGDIRECTORY) {
$ArtifactStagingFolder = $env:BUILD_ARTIFACTSTAGINGDIRECTORY
} else {
$ArtifactStagingFolder = Join-Path $RepoRoot (Join-Path obj _artifacts)
if (Test-Path $ArtifactStagingFolder) {
Remove-Item $ArtifactStagingFolder -Recurse -Force
}
}
$ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1" -CleanIfLocal
function Create-SymbolicLink {
param (
@ -29,7 +25,6 @@ function Create-SymbolicLink {
if (Test-Path $Link) { Remove-Item $Link }
$LinkContainer = Split-Path $Link -Parent
if (!(Test-Path $LinkContainer)) { mkdir $LinkContainer }
Write-Verbose "Linking $Link to $Target"
if ($IsMacOS -or $IsLinux) {
ln $Target $Link | Out-Null
} else {
@ -40,7 +35,7 @@ function Create-SymbolicLink {
# Stage all artifacts
$Artifacts = & "$PSScriptRoot\_all.ps1" -ArtifactNameSuffix $ArtifactNameSuffix
$Artifacts |% {
$DestinationFolder = (Join-Path (Join-Path $ArtifactStagingFolder "$($_.ArtifactName)$ArtifactNameSuffix") $_.ContainerFolder).TrimEnd('\')
$DestinationFolder = [System.IO.Path]::GetFullPath("$ArtifactStagingFolder/$($_.ArtifactName)$ArtifactNameSuffix/$($_.ContainerFolder)").TrimEnd('\')
$Name = "$(Split-Path $_.Source -Leaf)"
#Write-Host "$($_.Source) -> $($_.ArtifactName)\$($_.ContainerFolder)" -ForegroundColor Yellow
@ -51,7 +46,13 @@ $Artifacts |% {
}
}
$Artifacts |% { "$($_.ArtifactName)$ArtifactNameSuffix" } | Get-Unique |% {
$ArtifactNames = $Artifacts |% { "$($_.ArtifactName)$ArtifactNameSuffix" }
$ArtifactNames += Get-ChildItem env:ARTIFACTSTAGED_* |% {
# Return from ALLCAPS to the actual capitalization used for the artifact.
$artifactNameAllCaps = "$($_.Name.Substring('ARTIFACTSTAGED_'.Length))"
(Get-ChildItem $ArtifactStagingFolder\$artifactNameAllCaps* -Filter $artifactNameAllCaps).Name
}
$ArtifactNames | Get-Unique |% {
$artifact = New-Object -TypeName PSObject
Add-Member -InputObject $artifact -MemberType NoteProperty -Name Name -Value $_
Add-Member -InputObject $artifact -MemberType NoteProperty -Name Path -Value (Join-Path $ArtifactStagingFolder $_)

Просмотреть файл

@ -1,12 +1,7 @@
if ($env:BUILD_ARTIFACTSTAGINGDIRECTORY) {
$artifactsRoot = $env:BUILD_ARTIFACTSTAGINGDIRECTORY
} else {
$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
$artifactsRoot = "$RepoRoot\bin"
}
$ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1"
if (!(Test-Path $artifactsRoot/build_logs)) { return }
if (!(Test-Path $ArtifactStagingFolder/build_logs)) { return }
@{
"$artifactsRoot/build_logs" = (Get-ChildItem -Recurse "$artifactsRoot/build_logs")
"$ArtifactStagingFolder/build_logs" = (Get-ChildItem -Recurse "$ArtifactStagingFolder/build_logs")
}

Просмотреть файл

@ -0,0 +1,23 @@
$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
$coverageFiles = @(Get-ChildItem "$RepoRoot/test/*.cobertura.xml" -Recurse | Where {$_.FullName -notlike "*/In/*" -and $_.FullName -notlike "*\In\*" })
# Prepare code coverage reports for merging on another machine
if ($env:SYSTEM_DEFAULTWORKINGDIRECTORY) {
Write-Host "Substituting $env:SYSTEM_DEFAULTWORKINGDIRECTORY with `"{reporoot}`""
$coverageFiles |% {
$content = Get-Content -Path $_ |% { $_ -Replace [regex]::Escape($env:SYSTEM_DEFAULTWORKINGDIRECTORY), "{reporoot}" }
Set-Content -Path $_ -Value $content -Encoding UTF8
}
} else {
Write-Warning "coverageResults: Azure Pipelines not detected. Machine-neutral token replacement skipped."
}
if (!((Test-Path $RepoRoot\bin) -and (Test-Path $RepoRoot\obj))) { return }
@{
$RepoRoot = (
$coverageFiles +
(Get-ChildItem "$RepoRoot\obj\*.cs" -Recurse)
);
}

Просмотреть файл

@ -4,7 +4,7 @@ if (!$BuildConfiguration) {
$BuildConfiguration = 'Debug'
}
$PackagesRoot = "$RepoRoot/bin/$BuildConfiguration/Packages"
$PackagesRoot = "$RepoRoot/bin/Packages/$BuildConfiguration"
if (!(Test-Path $PackagesRoot)) { return }

Просмотреть файл

@ -1,4 +1,5 @@
$BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../bin")
if (!(Test-Path $BinPath)) { return }
$symbolfiles = & "$PSScriptRoot/../Get-SymbolFiles.ps1" -Path $BinPath | Get-Unique
@{

Просмотреть файл

@ -1,14 +1,11 @@
[CmdletBinding()]
Param(
)
$result = @{}
if ($env:AGENT_TEMPDIRECTORY) {
# The DotNetCoreCLI uses an alternate location to publish these files
$guidRegex = '^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$'
$result[$env:AGENT_TEMPDIRECTORY] = (Get-ChildItem $env:AGENT_TEMPDIRECTORY -Directory |? { $_.Name -match $guidRegex } |% { Get-ChildItem "$($_.FullName)\dotnet*.dmp","$($_.FullName)\testhost*.dmp","$($_.FullName)\Sequence_*.xml" -Recurse });
}
else {
$testRoot = Resolve-Path "$PSScriptRoot\..\..\test"
$result[$testRoot] = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File)
}
$testRoot = Resolve-Path "$PSScriptRoot\..\..\test"
$result[$testRoot] = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File)
$testlogsPath = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY\test_logs"
if (Test-Path $testlogsPath) {

Просмотреть файл

@ -1,11 +1,6 @@
# This doesn't work off Windows, nor do we need to convert symbols on multiple OS agents
if ($IsMacOS -or $IsLinux) {
return;
}
$BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..\bin")
$BinPath = [System.IO.Path]::GetFullPath("$PSScriptRoot/../../bin")
if (!(Test-Path $BinPath)) { return }
$symbolfiles = & "$PSScriptRoot\..\Get-SymbolFiles.ps1" -Path $BinPath -Tests | Get-Unique
$symbolfiles = & "$PSScriptRoot/../Get-SymbolFiles.ps1" -Path $BinPath -Tests | Get-Unique
@{
"$BinPath" = $SymbolFiles;

Просмотреть файл

@ -3,6 +3,9 @@ parameters:
type: object
default:
vmImage: windows-2022
- name: RunTests
type: boolean
default: true
jobs:
- job: Windows
@ -11,11 +14,31 @@ jobs:
- group: pinvoke code signing
steps:
- checkout: self
fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
clean: true
- template: install-dependencies.yml
- powershell: '& (./azure-pipelines/Get-nbgv.ps1) cloud -p src -c'
displayName: Set build number
- powershell: '& (./azure-pipelines/Get-nbgv.ps1) cloud -c'
displayName: Set build number
- template: dotnet.yml
parameters:
RunTests: ${{ parameters.RunTests }}
- template: expand-template.yml
- job: WrapUp
dependsOn:
- Windows
pool: ${{ parameters.windowsPool }} # Use Windows agent because PublishSymbols task requires it (https://github.com/microsoft/azure-pipelines-tasks/issues/13821).
condition: succeededOrFailed()
steps:
- checkout: self
fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
clean: true
- template: install-dependencies.yml
parameters:
initArgs: -NoRestore
- template: publish-symbols.yml
- ${{ if parameters.RunTests }}:
- template: publish-codecoverage.yml
- template: publish-deployables.yml

Просмотреть файл

@ -0,0 +1,83 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Runs tests as they are run in cloud test runs.
.PARAMETER Configuration
The configuration within which to run tests
.PARAMETER Agent
The name of the agent. This is used in preparing test run titles.
.PARAMETER PublishResults
A switch to publish results to Azure Pipelines.
.PARAMETER x86
A switch to run the tests in an x86 process.
.PARAMETER dotnet32
The path to a 32-bit dotnet executable to use.
#>
[CmdletBinding()]
Param(
[string]$Configuration='Debug',
[string]$Agent='Local',
[switch]$PublishResults,
[switch]$x86,
[string]$dotnet32
)
$RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path
$ArtifactStagingFolder = & "$PSScriptRoot/Get-ArtifactsStagingDirectory.ps1"
$dotnet = 'dotnet'
if ($x86) {
$x86RunTitleSuffix = ", x86"
if ($dotnet32) {
$dotnet = $dotnet32
} else {
$dotnet32Possibilities = "$PSScriptRoot\../obj/tools/x86/.dotnet/dotnet.exe", "$env:AGENT_TOOLSDIRECTORY/x86/dotnet/dotnet.exe", "${env:ProgramFiles(x86)}\dotnet\dotnet.exe"
$dotnet32Matches = $dotnet32Possibilities |? { Test-Path $_ }
if ($dotnet32Matches) {
$dotnet = Resolve-Path @($dotnet32Matches)[0]
Write-Host "Running tests using `"$dotnet`"" -ForegroundColor DarkGray
} else {
Write-Error "Unable to find 32-bit dotnet.exe"
return 1
}
}
}
& $dotnet test $RepoRoot `
--no-build `
-c $Configuration `
--filter "TestCategory!=FailsInCloudTest" `
--collect "Code Coverage;Format=cobertura" `
--settings "$PSScriptRoot/test.runsettings" `
--blame-hang-timeout 60s `
--blame-crash `
-bl:"$ArtifactStagingFolder/build_logs/test.binlog" `
--diag "$ArtifactStagingFolder/test_logs/diag.log;TraceLevel=info" `
--logger trx `
$unknownCounter = 0
Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx |% {
Copy-Item $_ -Destination $ArtifactStagingFolder/test_logs/
if ($PublishResults) {
$x = [xml](Get-Content -Path $_)
$runTitle = $null
if ($x.TestRun.TestDefinitions -and $x.TestRun.TestDefinitions.GetElementsByTagName('UnitTest')) {
$storage = $x.TestRun.TestDefinitions.GetElementsByTagName('UnitTest')[0].storage -replace '\\','/'
if ($storage -match '/(?<tfm>net[^/]+)/(?:(?<rid>[^/]+)/)?(?<lib>[^/]+)\.dll$') {
if ($matches.rid) {
$runTitle = "$($matches.lib) ($($matches.tfm), $($matches.rid), $Agent)"
} else {
$runTitle = "$($matches.lib) ($($matches.tfm)$x86RunTitleSuffix, $Agent)"
}
}
}
if (!$runTitle) {
$unknownCounter += 1;
$runTitle = "unknown$unknownCounter ($Agent$x86RunTitleSuffix)";
}
Write-Host "##vso[results.publish type=VSTest;runTitle=$runTitle;publishRunAttachments=true;resultFiles=$_;failTaskOnFailedTests=true;testRunSystem=VSTS - PTR;]"
}
}

Просмотреть файл

@ -1,55 +1,35 @@
parameters:
RunTests:
steps:
- task: VSBuild@1
displayName: Build Visual Studio solution
displayName: 🛠 msbuild
inputs:
msbuildArgs: /t:build,pack /m /v:m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/msbuild.binlog"
platform: Any CPU
configuration: $(BuildConfiguration)
- powershell: .\build.ps1 -Test
displayName: Test
displayName: 🧪 test
failOnStderr: true
- pwsh: >
dotnet tool install --tool-path obj SignClient
obj/SignClient sign
--baseDirectory '$(System.DefaultWorkingDirectory)/bin/$(BuildConfiguration)/Packages'
--input '**/*'
--config '$(System.DefaultWorkingDirectory)/azure-pipelines/SignClient.json'
--filelist '$(System.DefaultWorkingDirectory)/azure-pipelines/signfiles.txt'
--user '$(codesign_username)'
--secret '$(codesign_secret)'
--name 'PInvoke'
--descriptionUrl 'https://github.com/dotnet/pinvoke'
displayName: Code sign
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest'))
condition: and(succeeded(), ${{ parameters.RunTests }})
- powershell: azure-pipelines/variables/_pipelines.ps1
failOnStderr: true
displayName: Update pipeline variables based on build outputs
displayName: ⚙ Update pipeline variables based on build outputs
condition: succeededOrFailed()
- powershell: azure-pipelines/artifacts/_pipelines.ps1 -ArtifactNameSuffix "-$(Agent.JobName)"
- powershell: azure-pipelines/artifacts/_pipelines.ps1 -ArtifactNameSuffix "-$(Agent.JobName)" -Verbose
failOnStderr: true
displayName: Publish artifacts
displayName: 📢 Publish artifacts
condition: succeededOrFailed()
- task: PublishSymbols@2
inputs:
SymbolsFolder: $(Build.ArtifactStagingDirectory)/symbols-$(Agent.JobName)
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
displayName: Publish symbols to symbol server
condition: eq(variables['Agent.OS'], 'Windows_NT') # Execute on failed test runs too. Windows-only till https://github.com/microsoft/azure-pipelines-tasks/issues/13821 is fixed.
- task: PublishSymbols@2
inputs:
SymbolsFolder: $(Build.ArtifactStagingDirectory)/test_symbols-$(Agent.JobName)
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
displayName: Publish test symbols to symbol server
condition: and(failed(), eq(variables['Agent.OS'], 'Windows_NT')) # Execute on failed test runs only.
- ${{ if and(ne(variables['codecov_token'], ''), parameters.RunTests) }}:
- powershell: |
$ArtifactStagingFolder = & "azure-pipelines/Get-ArtifactsStagingDirectory.ps1"
$CoverageResultsFolder = Join-Path $ArtifactStagingFolder "coverageResults-$(Agent.JobName)"
azure-pipelines/publish-CodeCov.ps1 -CodeCovToken "$(codecov_token)" -PathToCodeCoverage "$CoverageResultsFolder" -Name "$(Agent.JobName) Coverage Results" -Flags "$(Agent.JobName)Host,$(BuildConfiguration)"
displayName: 📢 Publish code coverage results to codecov.io
timeoutInMinutes: 3
continueOnError: true

Просмотреть файл

@ -3,8 +3,8 @@ parameters:
steps:
- task: NuGetAuthenticate@0
displayName: Authenticate NuGet feeds
- task: NuGetAuthenticate@1
displayName: 🔏 Authenticate NuGet feeds
inputs:
forceReinstallCredentialProvider: true
@ -17,9 +17,9 @@ steps:
if (Get-Command mono -ErrorAction SilentlyContinue) {
mono --version
}
displayName: Install prerequisites
displayName: Install prerequisites
- powershell: azure-pipelines/variables/_pipelines.ps1
failOnStderr: true
displayName: Set pipeline variables based on source
displayName: Set pipeline variables based on source
name: SetPipelineVariables

Просмотреть файл

@ -0,0 +1,30 @@
<#
.SYNOPSIS
Uploads code coverage to codecov.io
.PARAMETER CodeCovToken
Code coverage token to use
.PARAMETER PathToCodeCoverage
Path to root of code coverage files
.PARAMETER Name
Name to upload with codecoverge
.PARAMETER Flags
Flags to upload with codecoverge
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$CodeCovToken,
[Parameter(Mandatory=$true)]
[string]$PathToCodeCoverage,
[string]$Name,
[string]$Flags
)
$RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path
Get-ChildItem -Recurse -Path $PathToCodeCoverage -Filter "*.cobertura.xml" | % {
$relativeFilePath = Resolve-Path -relative $_.FullName
Write-Host "Uploading: $relativeFilePath" -ForegroundColor Yellow
& (& "$PSScriptRoot/Get-CodeCovTool.ps1") -t $CodeCovToken -f $relativeFilePath -R $RepoRoot -F $Flags -n $Name
}

Просмотреть файл

@ -0,0 +1,13 @@
steps:
- download: current
artifact: coverageResults-Windows
displayName: 🔻 Download Windows code coverage results
continueOnError: true
- powershell: azure-pipelines/Merge-CodeCoverage.ps1 -Path '$(Pipeline.Workspace)' -OutputFile coveragereport/merged.cobertura.xml -Format Cobertura -Verbose
displayName: ⚙ Merge coverage
- task: PublishCodeCoverageResults@1
displayName: 📢 Publish code coverage results to Azure DevOps
inputs:
codeCoverageTool: cobertura
summaryFileLocation: coveragereport/merged.cobertura.xml
failIfCoverageEmpty: true

Просмотреть файл

@ -1,10 +1,8 @@
steps:
- task: NuGetCommand@2
displayName: Push packages to CI feed
inputs:
command: push
packagesToPush: bin/$(BuildConfiguration)/Packages/*.nupkg
nuGetFeedType: internal
publishVstsFeed: $(ci_feed)
allowPackageConflicts: true
- download: current
displayName: 🔻 Download deployables
artifact: deployables-Windows
- powershell: dotnet nuget push "$(Resolve-Path '$(Pipeline.Workspace)\deployables-Windows\')*.nupkg" -s $(ci_feed) -k azdo --skip-duplicate
displayName: 📦 Push packages to CI feed
condition: and(succeeded(), ne(variables['ci_feed'], ''), ne(variables['Build.Reason'], 'PullRequest'))

Просмотреть файл

@ -0,0 +1,30 @@
steps:
- task: DownloadPipelineArtifact@2
inputs:
artifact: symbols-Windows
path: $(Pipeline.Workspace)/symbols/Windows
displayName: 🔻 Download Windows symbols
continueOnError: true
- task: DownloadPipelineArtifact@2
inputs:
artifact: test_symbols-Windows
path: $(Pipeline.Workspace)/test_symbols/Windows
displayName: 🔻 Download Windows test symbols
continueOnError: true
- task: PublishSymbols@2
inputs:
SymbolsFolder: $(Pipeline.Workspace)/symbols
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
displayName: 📢 Publish symbols
- task: PublishSymbols@2
inputs:
SymbolsFolder: $(Pipeline.Workspace)/test_symbols
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
displayName: 📢 Publish test symbols

Просмотреть файл

@ -9,72 +9,52 @@ resources:
tags:
- auto-release
stages:
- stage: GitHubRelease
displayName: GitHub Release
jobs:
- deployment: create
pool:
vmImage: ubuntu-latest
environment: No-Approval
strategy:
runOnce:
deploy:
steps:
- powershell: |
Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)"
displayName: Set pipeline name
- download: CI
artifact: pinvoke_coverage_report-Windows
displayName: Downloading pinvoke coverage report
- download: CI
artifact: pinvoke_method_coverage-Windows
displayName: Downloading pinvoke method coverage
- task: GitHubRelease@1
displayName: GitHub release (create)
inputs:
gitHubConnection: github.com_AArnott_OAuth
repositoryName: $(Build.Repository.Name)
target: $(resources.pipeline.CI.sourceCommit)
tagSource: userSpecifiedTag
tag: v$(resources.pipeline.CI.runName)
title: v$(resources.pipeline.CI.runName)
isDraft: true # After running this step, visit the new draft release, edit, and publish.
assets: |
$(Pipeline.Workspace)/CI/pinvoke_method_coverage-Windows/*
$(Pipeline.Workspace)/CI/pinvoke_coverage_report-Windows/*
changeLogCompareToRelease: lastNonDraftRelease
changeLogType: issueBased
changeLogLabels: |
[
{ "label" : "bug", "displayName" : "Fixes", "state" : "closed" },
{ "label" : "enhancement", "displayName": "Enhancements", "state" : "closed" }
]
variables:
- group: Publishing secrets
- stage: nuget_org
displayName: nuget.org
dependsOn: GitHubRelease
jobs:
- deployment: push
pool:
vmImage: ubuntu-latest
environment: No-Approval
strategy:
runOnce:
deploy:
steps:
- download: CI
artifact: deployables-Windows
displayName: Download deployables-Windows artifact
patterns: 'deployables-Windows/**/*.*nupkg'
- task: NuGetToolInstaller@1
displayName: Use NuGet 5.x
inputs:
versionSpec: 5.x
- task: NuGetCommand@2
displayName: NuGet push
inputs:
command: push
packagesToPush: $(Pipeline.Workspace)/CI/deployables-Windows/*.nupkg
nuGetFeedType: external
publishFeedCredentials: nuget.org
jobs:
- job: release
pool:
vmImage: ubuntu-latest
steps:
- checkout: none
- powershell: |
Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)"
if ('$(resources.pipeline.CI.runName)'.Contains('-')) {
Write-Host "##vso[task.setvariable variable=IsPrerelease]true"
} else {
Write-Host "##vso[task.setvariable variable=IsPrerelease]false"
}
displayName: ⚙ Set up pipeline
- task: UseDotNet@2
displayName: ⚙ Install .NET SDK
inputs:
packageType: sdk
version: 6.x
- download: CI
artifact: deployables-Windows
displayName: 🔻 Download deployables-Windows artifact
patterns: 'deployables-Windows/*'
- task: GitHubRelease@1
displayName: 📢 GitHub release (create)
inputs:
gitHubConnection: github.com_AArnott_OAuth
repositoryName: $(Build.Repository.Name)
target: $(resources.pipeline.CI.sourceCommit)
tagSource: userSpecifiedTag
tag: v$(resources.pipeline.CI.runName)
title: v$(resources.pipeline.CI.runName)
isDraft: true # After running this step, visit the new draft release, edit, and publish.
isPreRelease: $(IsPrerelease)
assets: $(Pipeline.Workspace)/CI/deployables-Windows/*.nupkg
changeLogCompareToRelease: lastNonDraftRelease
changeLogType: issueBased
changeLogLabels: |
[
{ "label" : "breaking change", "displayName" : "Breaking changes", "state" : "closed" },
{ "label" : "bug", "displayName" : "Fixes", "state" : "closed" },
{ "label" : "enhancement", "displayName": "Enhancements", "state" : "closed" }
]
- script: dotnet nuget push $(Pipeline.Workspace)/CI/deployables-Windows/*.nupkg -s https://api.nuget.org/v3/index.json --api-key $(NuGetOrgApiKey) --skip-duplicate
displayName: 📦 Push packages to nuget.org
condition: and(succeeded(), ne(variables['NuGetOrgApiKey'], ''))

Просмотреть файл

@ -0,0 +1,44 @@
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>
<ModulePaths>
<Include>
<ModulePath>\.dll$</ModulePath>
<ModulePath>\.exe$</ModulePath>
</Include>
<Exclude>
<ModulePath>xunit\..*</ModulePath>
</Exclude>
</ModulePaths>
<Attributes>
<Exclude>
<Attribute>^System\.Diagnostics\.DebuggerHiddenAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.DebuggerNonUserCodeAttribute$</Attribute>
<Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>
<!-- We recommend you do not change the following values: -->
<!-- Set this to True to collect coverage information for functions marked with the "SecuritySafeCritical" attribute. Instead of writing directly into a memory location from such functions, code coverage inserts a probe that redirects to another function, which in turns writes into memory. -->
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
<!-- When set to True, collects coverage information from child processes that are launched with low-level ACLs, for example, UWP apps. -->
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
<!-- When set to True, collects coverage information from child processes that are launched by test or production code. -->
<CollectFromChildProcesses>True</CollectFromChildProcesses>
<!-- When set to True, restarts the IIS process and collects coverage information from it. -->
<CollectAspDotNet>False</CollectAspDotNet>
<!-- When set to True, static native instrumentation will be enabled. -->
<EnableStaticNativeInstrumentation>True</EnableStaticNativeInstrumentation>
<!-- When set to True, dynamic native instrumentation will be enabled. -->
<EnableDynamicNativeInstrumentation>True</EnableDynamicNativeInstrumentation>
<!-- When set to True, instrumented binaries on disk are removed and original files are restored. -->
<EnableStaticNativeInstrumentationRestore>True</EnableStaticNativeInstrumentationRestore>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>

Просмотреть файл

@ -1,7 +1,14 @@
#!/usr/bin/env pwsh
# This script returns a hashtable of build variables that should be set
# at the start of a build or release definition's execution.
<#
.SYNOPSIS
This script returns a hashtable of build variables that should be set
at the start of a build or release definition's execution.
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param (
)
$vars = @{}

Просмотреть файл

@ -1,13 +1,20 @@
# This script translates the variables returned by the _all.ps1 script
# into commands that instruct Azure Pipelines to actually set those variables for other pipeline tasks to consume.
<#
.SYNOPSIS
This script translates the variables returned by the _all.ps1 script
into commands that instruct Azure Pipelines to actually set those variables for other pipeline tasks to consume.
# The build or release definition may have set these variables to override
# what the build would do. So only set them if they have not already been set.
The build or release definition may have set these variables to override
what the build would do. So only set them if they have not already been set.
#>
[CmdletBinding()]
param (
)
(& "$PSScriptRoot\_all.ps1").GetEnumerator() |% {
# Always use ALL CAPS for env var names since Azure Pipelines converts variable names to all caps and on non-Windows OS, env vars are case sensitive.
$keyCaps = $_.Key.ToUpper()
if (Test-Path -Path "env:$keyCaps") {
if ((Test-Path "env:$keyCaps") -and (Get-Content "env:$keyCaps")) {
Write-Host "Skipping setting $keyCaps because variable is already set to '$(Get-Content env:$keyCaps)'." -ForegroundColor Cyan
} else {
Write-Host "$keyCaps=$($_.Value)" -ForegroundColor Yellow

Просмотреть файл

@ -1,6 +1,8 @@
{
"sdk": {
"version": "6.0.301"
"version": "6.0.401",
"rollForward": "patch",
"allowPrerelease": false
},
"msbuild-sdks": {
"MSBuild.Sdk.Extras": "3.0.44"

Просмотреть файл

@ -77,7 +77,7 @@ try {
if (!$NoRestore -and $PSCmdlet.ShouldProcess("NuGet packages", "Restore")) {
Write-Host "Restoring NuGet packages" -ForegroundColor $HeaderColor
dotnet restore src
dotnet restore
if ($lastexitcode -ne 0) {
throw "Failure while restoring packages."
}

0
src/.editorconfig Normal file
Просмотреть файл

6
src/AssemblyInfo.cs Normal file
Просмотреть файл

@ -0,0 +1,6 @@
// Copyright (c) COMPANY-PLACEHOLDER. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Runtime.InteropServices;
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]

Просмотреть файл

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Microsoft Managed Recommended Rules" Description="These rules focus on the most critical problems in your code, including potential security holes, application crashes, and other important logic and design errors. It is recommended to include this rule set in any custom rule set you create for your projects." ToolsVersion="10.0">
<Include Path="../PInvoke.ruleset" Action="Default" />
<Rules AnalyzerId="Roslyn.Diagnostics.Analyzers" RuleNamespace="Roslyn.Diagnostics.Analyzers">
<Rule Id="RS0026" Action="None" />
<Rule Id="RS0027" Action="None" />
</Rules>
</RuleSet>

Просмотреть файл

@ -1,119 +1,3 @@
<Project>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<RepoRootPath>$([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\'))</RepoRootPath>
<BaseIntermediateOutputPath>$(RepoRootPath)obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
<BaseOutputPath Condition=" '$(BaseOutputPath)' == '' ">$(RepoRootPath)bin\</BaseOutputPath>
<PackageOutputPath>$(RepoRootPath)bin\$(Configuration)\Packages\</PackageOutputPath>
<LangVersion>10.0</LangVersion>
<!-- <Nullable>enable</Nullable> -->
<AnalysisLevel>latest</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<!-- This entire repo has just one version.json file, so compute the version once and share with all projects in a large build. -->
<GitVersionBaseDirectory>$(MSBuildThisFileDirectory)../</GitVersionBaseDirectory>
<!-- Local builds should embed PDBs so we never lose them when a subsequent build occurs. -->
<DebugType Condition=" '$(CI)' != 'true' and '$(TF_BUILD)' != 'true' ">embedded</DebugType>
<DesktopOnlyFrameworks>net45</DesktopOnlyFrameworks>
<PlatformSpecificFrameworks>$(DesktopOnlyFrameworks);uap10.0.19041</PlatformSpecificFrameworks>
<PortableOnlyFrameworks>netstandard2.0</PortableOnlyFrameworks>
<PlatformAndPortableFrameworks>$(PortableOnlyFrameworks);$(PlatformSpecificFrameworks)</PlatformAndPortableFrameworks>
<TargetPlatformMinVersion Condition=" '$(TargetFramework)' == 'win8' ">8.0</TargetPlatformMinVersion>
<Title>PInvoke.$(MSBuildProjectName)</Title>
<Authors>Andrew Arnott</Authors>
<Summary>P/Invoke methods for the Windows $(MSBuildProjectName).dll.</Summary>
<Description>P/Invoke methods for the Windows $(MSBuildProjectName).dll.</Description>
<PackageProjectUrl>https://github.com/dotnet/pinvoke</PackageProjectUrl>
<Copyright>Copyright © .NET Foundation and Contributors</Copyright>
<Tags>pinvoke .net pcl</Tags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols Condition=" '$(DebugType)' != 'embedded' ">true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<NoWarn>$(NoWarn);CS1591;CA1401</NoWarn>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)PInvoke.ruleset</CodeAnalysisRuleSet>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)opensource.snk</AssemblyOriginatorKeyFile>
<IsTestProject>$(MSBuildProjectName.Contains('Test'))</IsTestProject>
<IsCodeGenerationProject Condition=" $(MSBuildProjectName.Contains('CodeGeneration')) ">true</IsCodeGenerationProject>
<IsPInvokeProject Condition=" '$(IsTestProject)' != 'true' and '$(IsCodeGenerationProject)' != 'true' ">true</IsPInvokeProject>
<IsPackable Condition=" '$(IsTestProject)' == 'true' or '$(IsCodeGenerationProject)' == 'true' ">false</IsPackable>
<ProduceReferenceAssembly Condition=" '$(IsTestProject)' != 'true' ">true</ProduceReferenceAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(IsCodeGenerationProject)' != 'true' ">
<RootNamespace>PInvoke</RootNamespace>
<AssemblyName>PInvoke.$(MSBuildProjectName)</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(IsTestProject)' == 'true' ">
<OutputPath>$(RepoRootPath)bin\$(Configuration)\tests\$(MSBuildProjectName)\</OutputPath>
<RootNamespace />
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)PInvoke.Tests.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemDefinitionGroup>
<!-- We build all libraries to a common directory, so avoid trying to copy P2P refs to the directory
to avoid wasting time with file collisions and build warnings. -->
<ProjectReference Condition=" '$(IsTestProject)' != 'true' ">
<!-- Sadly, enabling this optimization breaks loading the assembly later for exporting p/invoke method coverage. -->
<!-- <Private>false</Private> -->
</ProjectReference>
</ItemDefinitionGroup>
<ItemGroup>
<GeneratorAssemblySearchPaths Include="$(RepoRootPath)bin\$(Configuration)\netstandard2.0\" />
<AdditionalFiles Include="$(MSBuildThisFileDirectory)../stylecop.json"/>
<None Include="$(MSBuildProjectName).exports.txt" Condition=" Exists('$(MSBuildProjectName).exports.txt') and '$(TargetFramework)' == 'net45' ">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemDefinitionGroup>
<!-- We always want MSBuild properties generated that point at the restored location of each package. -->
<PackageReference GeneratePathProperty="true" />
</ItemDefinitionGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.54-alpha" PrivateAssets="all" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.354" PrivateAssets="all" />
</ItemGroup>
<ItemGroup Condition=" '$(IsCodeGenerationProject)' != 'true' ">
<ProjectReference Include="..\CodeGenerationAttributes\CodeGenerationAttributes.csproj" PrivateAssets="all">
<Private>false</Private>
<OutputItemType>Analyzer</OutputItemType>
</ProjectReference>
<ProjectReference Include="..\CodeGeneration\CodeGeneration.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<OutputItemType>Analyzer</OutputItemType>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
<UndefineProperties>TargetFramework</UndefineProperties>
<Private>false</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup Condition=" '$(IsTestProject)' == 'true' ">
<PackageReference Include="coverlet.msbuild" Version="3.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit.runner.console" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>
<Target Name="PrepareReleaseNotes" BeforeTargets="GenerateNuspec" DependsOnTargets="GetBuildVersion">
<PropertyGroup>
<PackageReleaseNotes>https://github.com/dotnet/pinvoke/releases/tag/v$(Version)</PackageReleaseNotes>
</PropertyGroup>
</Target>
<Project>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.props))\Directory.Build.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.props))' != '' " />
</Project>

Просмотреть файл

@ -1,36 +1,7 @@
<Project>
<PropertyGroup>
<RootNamespace Condition=" '$(IsTestProject)' == 'true' " />
<ExcludeStoreBannedAPIs Condition=" ('$(TargetPlatformIdentifier)' == 'Windows' or '$(TargetPlatformIdentifier)' == 'UAP') and '$(TargetPlatformVersion)' >= 8.0 ">true</ExcludeStoreBannedAPIs>
<DefineConstants Condition=" '$(ExcludeStoreBannedAPIs)' != 'true' ">$(DefineConstants);IncludeStoreBannedAPIs</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' or ('$(TargetFrameworkIdentifier)' == '.NETStandard' and '$(_TargetFrameworkVersionWithoutV)' >= 2.0) ">$(DefineConstants);Serialization</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' == '.NETStandard' and '$(_TargetFrameworkVersionWithoutV)' >= 2.0 ">$(DefineConstants);NETSTANDARD2_0_ORLATER</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(_TargetFrameworkVersionWithoutV)' >= 4.5 ">$(DefineConstants);NET45_ORLATER</DefineConstants>
<DefineConstants Condition=" '$(TargetFrameworkIdentifier)' != '.NETFramework' ">$(DefineConstants);APISets</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(IsTestProject)' == 'true' ">
<CoverletOutputFormat>cobertura</CoverletOutputFormat>
<Exclude>[xunit.*]*</Exclude>
<!-- Ensure we preserve each coverlet output file per target framework: https://github.com/tonerdo/coverlet/issues/177 -->
<CoverletOutput>$(OutputPath)/</CoverletOutput>
</PropertyGroup>
<ItemGroup>
<Compile Remove="storebanned\**" Condition=" '$(ExcludeStoreBannedAPIs)' == 'true' " />
<Compile Remove="**" Condition=" '$(ExcludeStoreBannedAPIs)' == 'true' and '$(StoreBanned)' == 'true' " />
<Compile Include="$(MSBuildThisFileDirectory)AssemblyAttributes.cs" Condition=" '$(IsPInvokeProject)' == 'true' " />
<Compile Include="$(MSBuildThisFileDirectory)AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(IsPInvokeProject)' == 'true' and '$(MSBuildProjectName)' != 'Win32' and '$(TargetFramework)' == 'net45' ">
<PackageReference Include="Roslyn.Diagnostics.Analyzers" Version="1.2.0-beta2" PrivateAssets="all" />
<AdditionalFiles Include="PublicAPI.Shipped.txt" />
<AdditionalFiles Include="PublicAPI.Unshipped.txt" />
</ItemGroup>
<Import Project="$(MSBuildThisFileDirectory)PInvoke.Extra.targets" Condition=" '$(IsTestProject)' != 'true' and '$(IsCodeGenerationProject)' != 'true' "/>
<!-- Workaround win8 .targets defining a target that should be blank (https://github.com/dotnet/sdk/issues/2517) -->
<Target Name="GetPackagingOutputs" />
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.targets))\Directory.Build.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.targets))' != '' " />
</Project>

Просмотреть файл

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Microsoft Managed Recommended Rules" Description="These rules focus on the most critical problems in your code, including potential security holes, application crashes, and other important logic and design errors. It is recommended to include this rule set in any custom rule set you create for your projects." ToolsVersion="17.0">
<Localization ResourceAssembly="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.dll" ResourceBaseName="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.Localized">
<Name Resource="MinimumRecommendedRules_Name" />
<Description Resource="MinimumRecommendedRules_Description" />
</Localization>
<Include Path="pinvoke.ruleset" Action="Default" />
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.CodeAnalysis.NetAnalyzers">
<Rule Id="CA1050" Action="None" />
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="SA1601" Action="Hidden" />
<Rule Id="SA1652" Action="None" />
</Rules>
</RuleSet>

Просмотреть файл

@ -1,89 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Microsoft Managed Recommended Rules" Description="These rules focus on the most critical problems in your code, including potential security holes, application crashes, and other important logic and design errors. It is recommended to include this rule set in any custom rule set you create for your projects." ToolsVersion="17.0">
<Localization ResourceAssembly="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.dll" ResourceBaseName="Microsoft.VisualStudio.CodeAnalysis.RuleSets.Strings.Localized">
<Name Resource="MinimumRecommendedRules_Name" />
<Description Resource="MinimumRecommendedRules_Description" />
</Localization>
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CA1001" Action="Warning" />
<Rule Id="CA1009" Action="Warning" />
<Rule Id="CA1016" Action="Warning" />
<Rule Id="CA1033" Action="Warning" />
<Rule Id="CA1049" Action="Warning" />
<Rule Id="CA1061" Action="Warning" />
<Rule Id="CA1063" Action="Warning" />
<Rule Id="CA1065" Action="Info" />
<Rule Id="CA1301" Action="Warning" />
<Rule Id="CA1400" Action="Warning" />
<Rule Id="CA1401" Action="Warning" />
<Rule Id="CA1403" Action="Warning" />
<Rule Id="CA1404" Action="Warning" />
<Rule Id="CA1405" Action="Warning" />
<Rule Id="CA1410" Action="Warning" />
<Rule Id="CA1415" Action="Warning" />
<Rule Id="CA1821" Action="Warning" />
<Rule Id="CA1900" Action="Warning" />
<Rule Id="CA1901" Action="Warning" />
<Rule Id="CA2002" Action="Warning" />
<Rule Id="CA2100" Action="Warning" />
<Rule Id="CA2101" Action="Info" />
<Rule Id="CA2108" Action="Warning" />
<Rule Id="CA2111" Action="Warning" />
<Rule Id="CA2112" Action="Warning" />
<Rule Id="CA2114" Action="Warning" />
<Rule Id="CA2116" Action="Warning" />
<Rule Id="CA2117" Action="Warning" />
<Rule Id="CA2122" Action="Warning" />
<Rule Id="CA2123" Action="Warning" />
<Rule Id="CA2124" Action="Warning" />
<Rule Id="CA2126" Action="Warning" />
<Rule Id="CA2131" Action="Warning" />
<Rule Id="CA2132" Action="Warning" />
<Rule Id="CA2133" Action="Warning" />
<Rule Id="CA2134" Action="Warning" />
<Rule Id="CA2137" Action="Warning" />
<Rule Id="CA2138" Action="Warning" />
<Rule Id="CA2140" Action="Warning" />
<Rule Id="CA2141" Action="Warning" />
<Rule Id="CA2146" Action="Warning" />
<Rule Id="CA2147" Action="Warning" />
<Rule Id="CA2149" Action="Warning" />
<Rule Id="CA2200" Action="Warning" />
<Rule Id="CA2202" Action="Warning" />
<Rule Id="CA2207" Action="Warning" />
<Rule Id="CA2212" Action="Warning" />
<Rule Id="CA2213" Action="Warning" />
<Rule Id="CA2214" Action="Warning" />
<Rule Id="CA2216" Action="Warning" />
<Rule Id="CA2220" Action="Warning" />
<Rule Id="CA2229" Action="Warning" />
<Rule Id="CA2231" Action="Warning" />
<Rule Id="CA2232" Action="Warning" />
<Rule Id="CA2235" Action="Warning" />
<Rule Id="CA2236" Action="Warning" />
<Rule Id="CA2237" Action="Warning" />
<Rule Id="CA2238" Action="Warning" />
<Rule Id="CA2240" Action="Warning" />
<Rule Id="CA2241" Action="Warning" />
<Rule Id="CA2242" Action="Warning" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp.CodeStyle" RuleNamespace="Microsoft.CodeAnalysis.CSharp.CodeStyle">
<Rule Id="IDE1006" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.CSharp.Features" RuleNamespace="Microsoft.CodeAnalysis.CSharp.Features">
<Rule Id="IDE0003" Action="None" />
<Rule Id="IDE1006" Action="None" />
</Rules>
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.CodeAnalysis.NetAnalyzers">
<Rule Id="CA1041" Action="Hidden" />
<Rule Id="CA1069" Action="Hidden" />
</Rules>
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<Rule Id="SA1307" Action="None" />
<Rule Id="SA1310" Action="None" />
<Rule Id="SA1313" Action="None" />
<Rule Id="SA1600" Action="Hidden" />
<Rule Id="SA1602" Action="Hidden" />
<Rule Id="SA1649" Action="Info" />
</Rules>
</RuleSet>

55
test/.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,55 @@
[*.cs]
# SA1600: Elements should be documented
dotnet_diagnostic.SA1600.severity = silent
# SA1601: Partial elements should be documented
dotnet_diagnostic.SA1601.severity = silent
# SA1602: Enumeration items should be documented
dotnet_diagnostic.SA1602.severity = silent
# SA1615: Element return value should be documented
dotnet_diagnostic.SA1615.severity = silent
# VSTHRD103: Call async methods when in an async method
dotnet_diagnostic.VSTHRD103.severity = silent
# VSTHRD111: Use .ConfigureAwait(bool)
dotnet_diagnostic.VSTHRD111.severity = none
# VSTHRD200: Use Async suffix for async methods
dotnet_diagnostic.VSTHRD200.severity = silent
# CA1014: Mark assemblies with CLSCompliant
dotnet_diagnostic.CA1014.severity = none
# CA1050: Declare types in namespaces
dotnet_diagnostic.CA1050.severity = none
# CA1303: Do not pass literals as localized parameters
dotnet_diagnostic.CA1303.severity = none
# CS1591: Missing XML comment for publicly visible type or member
dotnet_diagnostic.CS1591.severity = silent
# CA1707: Identifiers should not contain underscores
dotnet_diagnostic.CA1707.severity = silent
# CA1062: Validate arguments of public methods
dotnet_diagnostic.CA1062.severity = suggestion
# CA1063: Implement IDisposable Correctly
dotnet_diagnostic.CA1063.severity = silent
# CA1816: Dispose methods should call SuppressFinalize
dotnet_diagnostic.CA1816.severity = silent
# CA2007: Consider calling ConfigureAwait on the awaited task
dotnet_diagnostic.CA2007.severity = none
# SA1401: Fields should be private
dotnet_diagnostic.SA1401.severity = silent
# SA1133: Do not combine attributes
dotnet_diagnostic.SA1133.severity = silent

Просмотреть файл

@ -0,0 +1,9 @@
<Project>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.props))\Directory.Build.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.props))' != '' " />
<PropertyGroup>
<IsPackable>false</IsPackable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,3 @@
<Project>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.targets))\Directory.Build.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Build.targets))' != '' " />
</Project>

Просмотреть файл

@ -15,20 +15,28 @@
When using 'repo', environment variables are set to cause the locally installed dotnet SDK to be used.
Per-repo can lead to file locking issues when dotnet.exe is left running as a build server and can be mitigated by running `dotnet build-server shutdown`.
Per-machine requires elevation and will download and install all SDKs and runtimes to machine-wide locations so all applications can find it.
.PARAMETER IncludeX86
Installs a x86 SDK and runtimes in addition to the x64 ones. Only supported on Windows. Ignored on others.
#>
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')]
Param (
[ValidateSet('repo','user','machine')]
[string]$InstallLocality='user'
[string]$InstallLocality='user',
[switch]$IncludeX86
)
$DotNetInstallScriptRoot = "$PSScriptRoot/../obj/tools"
if (!(Test-Path $DotNetInstallScriptRoot)) { New-Item -ItemType Directory -Path $DotNetInstallScriptRoot -WhatIf:$false | Out-Null }
$DotNetInstallScriptRoot = Resolve-Path $DotNetInstallScriptRoot
# Look up actual required .NET Core SDK version from global.json
# Look up actual required .NET SDK version from global.json
$sdkVersion = & "$PSScriptRoot/../azure-pipelines/variables/DotNetSdkVersion.ps1"
If ($IncludeX86 -and ($IsMacOS -or $IsLinux)) {
Write-Verbose "Ignoring -IncludeX86 switch because 32-bit runtimes are only supported on Windows."
$IncludeX86 = $false
}
$arch = [System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture
if (!$arch) { # Windows Powershell leaves this blank
$arch = 'x64'
@ -38,16 +46,16 @@ if (!$arch) { # Windows Powershell leaves this blank
# Search for all .NET Core runtime versions referenced from MSBuild projects and arrange to install them.
$runtimeVersions = @()
$windowsDesktopRuntimeVersions = @()
Get-ChildItem "$PSScriptRoot\..\src\*.*proj","$PSScriptRoot\..\Directory.Build.props" -Recurse |% {
Get-ChildItem "$PSScriptRoot\..\src\*.*proj","$PSScriptRoot\..\test\*.*proj","$PSScriptRoot\..\Directory.Build.props" -Recurse |% {
$projXml = [xml](Get-Content -Path $_)
$pg = $projXml.Project.PropertyGroup
if ($pg) {
$targetFrameworks = $pg.TargetFramework
if (!$targetFrameworks) {
$targetFrameworks = $pg.TargetFrameworks
if ($targetFrameworks) {
$targetFrameworks = $targetFrameworks -Split ';'
}
$targetFrameworks = @()
$tf = $pg.TargetFramework
$targetFrameworks += $tf
$tfs = $pg.TargetFrameworks
if ($tfs) {
$targetFrameworks = $tfs -Split ';'
}
}
$targetFrameworks |? { $_ -match 'net(?:coreapp)?(\d+\.\d+)' } |% {
@ -72,6 +80,7 @@ Function Get-FileFromWeb([Uri]$Uri, $OutDir) {
$OutFile = Join-Path $OutDir $Uri.Segments[-1]
if (!(Test-Path $OutFile)) {
Write-Verbose "Downloading $Uri..."
if (!(Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null }
try {
(New-Object System.Net.WebClient).DownloadFile($Uri, $OutFile)
} finally {
@ -82,35 +91,67 @@ Function Get-FileFromWeb([Uri]$Uri, $OutDir) {
$OutFile
}
Function Get-InstallerExe($Version, [switch]$Runtime) {
$sdkOrRuntime = 'Sdk'
if ($Runtime) { $sdkOrRuntime = 'Runtime' }
Function Get-InstallerExe(
$Version,
$Architecture,
[ValidateSet('Sdk','Runtime','WindowsDesktop')]
[string]$sku
) {
# Get the latest/actual version for the specified one
if (([Version]$Version).Build -eq -1) {
$versionInfo = -Split (Invoke-WebRequest -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sdkOrRuntime/$Version/latest.version" -UseBasicParsing)
$TypedVersion = [Version]$Version
if ($TypedVersion.Build -eq -1) {
$versionInfo = -Split (Invoke-WebRequest -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sku/$Version/latest.version" -UseBasicParsing)
$Version = $versionInfo[-1]
}
Get-FileFromWeb -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sdkOrRuntime/$Version/dotnet-$($sdkOrRuntime.ToLowerInvariant())-$Version-win-$arch.exe" -OutDir "$DotNetInstallScriptRoot"
$majorMinor = "$($TypedVersion.Major).$($TypedVersion.Minor)"
$ReleasesFile = Join-Path $DotNetInstallScriptRoot "$majorMinor\releases.json"
if (!(Test-Path $ReleasesFile)) {
Get-FileFromWeb -Uri "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/$majorMinor/releases.json" -OutDir (Split-Path $ReleasesFile) | Out-Null
}
$releases = Get-Content $ReleasesFile | ConvertFrom-Json
$url = $null
foreach ($release in $releases.releases) {
$filesElement = $null
if ($release.$sku.version -eq $Version) {
$filesElement = $release.$sku.files
}
if ($filesElement) {
foreach ($file in $filesElement) {
if ($file.rid -eq "win-$Architecture") {
$url = $file.url
Break
}
}
if ($url) {
Break
}
}
}
if ($url) {
Get-FileFromWeb -Uri $url -OutDir $DotNetInstallScriptRoot
} else {
Write-Error "Unable to find release of $sku v$Version"
}
}
Function Install-DotNet($Version, [switch]$Runtime) {
if ($Runtime) { $sdkSubstring = '' } else { $sdkSubstring = 'SDK ' }
Write-Host "Downloading .NET Core $sdkSubstring$Version..."
$Installer = Get-InstallerExe -Version $Version -Runtime:$Runtime
Write-Host "Installing .NET Core $sdkSubstring$Version..."
Function Install-DotNet($Version, $Architecture, [ValidateSet('Sdk','Runtime','WindowsDesktop')][string]$sku = 'Sdk') {
Write-Host "Downloading .NET Core $sku $Version..."
$Installer = Get-InstallerExe -Version $Version -Architecture $Architecture -sku $sku
Write-Host "Installing .NET Core $sku $Version..."
cmd /c start /wait $Installer /install /passive /norestart
if ($LASTEXITCODE -eq 3010) {
Write-Verbose "Restart required"
} elseif ($LASTEXITCODE -ne 0) {
throw "Failure to install .NET Core SDK"
throw "Failure to install .NET SDK"
}
}
$switches = @(
'-Architecture',$arch
)
$switches = @()
$envVars = @{
# For locally installed dotnet, skip first time experience which takes a long time
'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' = 'true';
@ -121,15 +162,37 @@ if ($InstallLocality -eq 'machine') {
$DotNetInstallDir = '/usr/share/dotnet'
} else {
$restartRequired = $false
if ($PSCmdlet.ShouldProcess(".NET Core SDK $sdkVersion", "Install")) {
Install-DotNet -Version $sdkVersion
if ($PSCmdlet.ShouldProcess(".NET SDK $sdkVersion", "Install")) {
Install-DotNet -Version $sdkVersion -Architecture $arch
$restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010)
if ($IncludeX86) {
Install-DotNet -Version $sdkVersion -Architecture x86
$restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010)
}
}
$runtimeVersions | Get-Unique |% {
if ($PSCmdlet.ShouldProcess(".NET Core runtime $_", "Install")) {
Install-DotNet -Version $_ -Runtime
$runtimeVersions | Sort-Object | Get-Unique |% {
if ($PSCmdlet.ShouldProcess(".NET runtime $_", "Install")) {
Install-DotNet -Version $_ -sku Runtime -Architecture $arch
$restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010)
if ($IncludeX86) {
Install-DotNet -Version $_ -sku Runtime -Architecture x86
$restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010)
}
}
}
$windowsDesktopRuntimeVersions | Sort-Object | Get-Unique |% {
if ($PSCmdlet.ShouldProcess(".NET Windows Desktop $_", "Install")) {
Install-DotNet -Version $_ -sku WindowsDesktop -Architecture $arch
$restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010)
if ($IncludeX86) {
Install-DotNet -Version $_ -sku WindowsDesktop -Architecture x86
$restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010)
}
}
}
@ -142,20 +205,34 @@ if ($InstallLocality -eq 'machine') {
}
} elseif ($InstallLocality -eq 'repo') {
$DotNetInstallDir = "$DotNetInstallScriptRoot/.dotnet"
$DotNetX86InstallDir = "$DotNetInstallScriptRoot/x86/.dotnet"
} elseif ($env:AGENT_TOOLSDIRECTORY) {
$DotNetInstallDir = "$env:AGENT_TOOLSDIRECTORY/dotnet"
$DotNetX86InstallDir = "$env:AGENT_TOOLSDIRECTORY/x86/dotnet"
} else {
$DotNetInstallDir = Join-Path $HOME .dotnet
}
Write-Host "Installing .NET Core SDK and runtimes to $DotNetInstallDir" -ForegroundColor Blue
if ($DotNetInstallDir) {
$switches += '-InstallDir',"`"$DotNetInstallDir`""
if (!(Test-Path $DotNetInstallDir)) { New-Item -ItemType Directory -Path $DotNetInstallDir }
$DotNetInstallDir = Resolve-Path $DotNetInstallDir
Write-Host "Installing .NET SDK and runtimes to $DotNetInstallDir" -ForegroundColor Blue
$envVars['DOTNET_MULTILEVEL_LOOKUP'] = '0'
$envVars['DOTNET_ROOT'] = $DotNetInstallDir
}
if ($IncludeX86) {
if ($DotNetX86InstallDir) {
if (!(Test-Path $DotNetX86InstallDir)) { New-Item -ItemType Directory -Path $DotNetX86InstallDir }
$DotNetX86InstallDir = Resolve-Path $DotNetX86InstallDir
Write-Host "Installing x86 .NET SDK and runtimes to $DotNetX86InstallDir" -ForegroundColor Blue
} else {
# Only machine-wide or repo-wide installations can handle two unique dotnet.exe architectures.
Write-Error "The installation location or OS isn't supported for x86 installation. Try a different -InstallLocality value."
return 1
}
}
if ($IsMacOS -or $IsLinux) {
$DownloadUri = "https://raw.githubusercontent.com/dotnet/install-scripts/781752509a890ca7520f1182e8bae71f9a53d754/src/dotnet-install.sh"
$DotNetInstallScriptPath = "$DotNetInstallScriptRoot/dotnet-install.sh"
@ -179,47 +256,89 @@ $DotNetInstallScriptPathExpression = "& '$DotNetInstallScriptPathExpression'"
$anythingInstalled = $false
$global:LASTEXITCODE = 0
if ($PSCmdlet.ShouldProcess(".NET Core SDK $sdkVersion", "Install")) {
if ($PSCmdlet.ShouldProcess(".NET SDK $sdkVersion", "Install")) {
$anythingInstalled = $true
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Version $sdkVersion $switches"
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Version $sdkVersion -Architecture $arch -InstallDir $DotNetInstallDir $switches"
if ($LASTEXITCODE -ne 0) {
Write-Error ".NET SDK installation failure: $LASTEXITCODE"
exit $LASTEXITCODE
}
} else {
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Version $sdkVersion $switches -DryRun"
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Version $sdkVersion -Architecture $arch -InstallDir $DotNetInstallDir $switches -DryRun"
}
if ($IncludeX86) {
if ($PSCmdlet.ShouldProcess(".NET x86 SDK $sdkVersion", "Install")) {
$anythingInstalled = $true
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Version $sdkVersion -Architecture x86 -InstallDir $DotNetX86InstallDir $switches"
if ($LASTEXITCODE -ne 0) {
Write-Error ".NET x86 SDK installation failure: $LASTEXITCODE"
exit $LASTEXITCODE
}
} else {
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Version $sdkVersion -Architecture x86 -InstallDir $DotNetX86InstallDir $switches -DryRun"
}
}
$dotnetRuntimeSwitches = $switches + '-Runtime','dotnet'
$runtimeVersions | Sort-Object -Unique |% {
if ($PSCmdlet.ShouldProcess(".NET Core runtime $_", "Install")) {
if ($PSCmdlet.ShouldProcess(".NET Core $Arch runtime $_", "Install")) {
$anythingInstalled = $true
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ $dotnetRuntimeSwitches"
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture $arch -InstallDir $DotNetInstallDir $dotnetRuntimeSwitches"
if ($LASTEXITCODE -ne 0) {
Write-Error ".NET SDK installation failure: $LASTEXITCODE"
exit $LASTEXITCODE
}
} else {
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ $dotnetRuntimeSwitches -DryRun"
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture $arch -InstallDir $DotNetInstallDir $dotnetRuntimeSwitches -DryRun"
}
if ($IncludeX86) {
if ($PSCmdlet.ShouldProcess(".NET Core x86 runtime $_", "Install")) {
$anythingInstalled = $true
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture x86 -InstallDir $DotNetX86InstallDir $dotnetRuntimeSwitches"
if ($LASTEXITCODE -ne 0) {
Write-Error ".NET SDK installation failure: $LASTEXITCODE"
exit $LASTEXITCODE
}
} else {
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture x86 -InstallDir $DotNetX86InstallDir $dotnetRuntimeSwitches -DryRun"
}
}
}
$windowsDesktopRuntimeSwitches = $switches + '-Runtime','windowsdesktop'
$windowsDesktopRuntimeVersions | Sort-Object -Unique |% {
if ($PSCmdlet.ShouldProcess(".NET Core WindowsDesktop runtime $_", "Install")) {
if ($PSCmdlet.ShouldProcess(".NET Core WindowsDesktop $arch runtime $_", "Install")) {
$anythingInstalled = $true
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ $windowsDesktopRuntimeSwitches"
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture $arch -InstallDir $DotNetInstallDir $windowsDesktopRuntimeSwitches"
if ($LASTEXITCODE -ne 0) {
Write-Error ".NET SDK installation failure: $LASTEXITCODE"
exit $LASTEXITCODE
}
} else {
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ $windowsDesktopRuntimeSwitches -DryRun"
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture $arch -InstallDir $DotNetInstallDir $windowsDesktopRuntimeSwitches -DryRun"
}
if ($IncludeX86) {
if ($PSCmdlet.ShouldProcess(".NET Core WindowsDesktop x86 runtime $_", "Install")) {
$anythingInstalled = $true
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture x86 -InstallDir $DotNetX86InstallDir $windowsDesktopRuntimeSwitches"
if ($LASTEXITCODE -ne 0) {
Write-Error ".NET SDK installation failure: $LASTEXITCODE"
exit $LASTEXITCODE
}
} else {
Invoke-Expression -Command "$DotNetInstallScriptPathExpression -Channel $_ -Architecture x86 -InstallDir $DotNetX86InstallDir $windowsDesktopRuntimeSwitches -DryRun"
}
}
}

Просмотреть файл

@ -33,7 +33,7 @@ if ($IsMacOS -or $IsLinux) {
$installerScript = Join-Path $toolsPath $installerScript
if (!(Test-Path $installerScript)) {
if (!(Test-Path $installerScript) -or $Force) {
Invoke-WebRequest $sourceUrl -OutFile $installerScript
}
@ -43,7 +43,7 @@ if ($IsMacOS -or $IsLinux) {
chmod u+x $installerScript
}
& $installerScript -Force:$Force
& $installerScript -Force:$Force -AddNetfx -InstallNet6
if ($AccessToken) {
$endpoints = @()