Merge remote-tracking branch 'libtemplate/microbuild' into libtemplateUpdate

This commit is contained in:
Andrew Arnott 2022-11-04 11:35:10 -06:00
Родитель 739cfaa3de fff546b569
Коммит aabe7798d2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: F33A420C60ED9C6F
56 изменённых файлов: 1331 добавлений и 345 удалений

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

@ -167,5 +167,14 @@ 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

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

@ -9,6 +9,7 @@
*.user
*.userosscache
*.sln.docstates
*.lutconfig
launchSettings.json
# User-specific files (MonoDevelop/Xamarin Studio)
@ -139,6 +140,7 @@ _TeamCity*
# Visual Studio code coverage results
*.coverage
*.coveragexml
/coveragereport/
# NCrunch
_NCrunch_*

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

@ -7,5 +7,36 @@ FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com)
with any additional questions or comments.
We welcome 3rd party pull requests.
For significant changes we strongly recommend opening an issue to start a design discussion first.
## Best practices
* Use Windows PowerShell or [PowerShell Core][pwsh] (including on Linux/OSX) to run .ps1 scripts.
Some scripts set environment variables to help you, but they are only retained if you use PowerShell as your shell.
## Prerequisites
All dependencies can be installed by running the `init.ps1` script at the root of the repository
using Windows PowerShell or [PowerShell Core][pwsh] (on any OS).
Some dependencies installed by `init.ps1` may only be discoverable from the same command line environment the init script was run from due to environment variables, so be sure to launch Visual Studio or build the repo from that same environment.
Alternatively, run `init.ps1 -InstallLocality Machine` (which may require elevation) in order to install dependencies at machine-wide locations so Visual Studio and builds work everywhere.
The only prerequisite for building, testing, and deploying from this repository
is the [.NET SDK](https://get.dot.net/).
You should install the version specified in `global.json` or a later version within
the same major.minor.Bxx "hundreds" band.
For example if 2.2.300 is specified, you may install 2.2.300, 2.2.301, or 2.2.310
while the 2.2.400 version would not be considered compatible by .NET SDK.
See [.NET Core Versioning](https://docs.microsoft.com/dotnet/core/versions/) for more information.
## Package restore
The easiest way to restore packages may be to run `init.ps1` which automatically authenticates
to the feeds that packages for this repo come from, if any.
`dotnet restore` or `nuget restore` also work but may require extra steps to authenticate to any applicable feeds.
## Building
This repository can be built on Windows, Linux, and OSX.
Building, testing, and packing this repository can be done by using the standard dotnet CLI commands (e.g. `dotnet build`, `dotnet test`, `dotnet pack`, etc.).
[pwsh]: https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-6

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

@ -16,6 +16,9 @@
<!-- 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>
@ -30,20 +33,8 @@
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols Condition=" '$(DebugType)' != 'embedded' ">true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<MicroBuildVersion>2.0.68</MicroBuildVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Internal.MicroBuild.VisualStudio" Version="$(MicroBuildVersion)" PrivateAssets="all" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
<PackageReference Include="Nerdbank.GitVersioning" Version="3.5.107" PrivateAssets="all" />
<PackageReference Include="Nullable" Version="1.3.0" 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" />
</ItemGroup>
<ItemGroup>
<None Include="$(RepoRootPath)obj/NOTICE" Pack="true" PackagePath="" Visible="false" Condition=" Exists('$(RepoRootPath)obj/NOTICE') " />
</ItemGroup>
@ -79,7 +70,7 @@
It's also not necessary to generate these assets.
-->
<PropertyGroup Condition="'$(IsWpfTempProject)' == 'true'">
<_WpfTempProjectNuGetFilePathNoExt>$(RepoRootPath)obj\$(_TargetAssemblyProjectName)\$(_TargetAssemblyProjectName)$(MSBuildProjectExtension).nuget.g</_WpfTempProjectNuGetFilePathNoExt>
<_WpfTempProjectNuGetFilePathNoExt>$(BaseIntermediateOutputPath)..\$(_TargetAssemblyProjectName)\$(_TargetAssemblyProjectName)$(MSBuildProjectExtension).nuget.g</_WpfTempProjectNuGetFilePathNoExt>
<EnableSourceLink>false</EnableSourceLink>
<EmbedUntrackedSources>false</EmbedUntrackedSources>

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

@ -0,0 +1,25 @@
<Project>
<!-- https://learn.microsoft.com/nuget/consume-packages/central-package-management -->
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<MicroBuildVersion>2.0.87</MicroBuildVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageVersion Include="Moq" Version="4.18.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageVersion Include="xunit" Version="2.4.2" />
</ItemGroup>
<ItemGroup>
<GlobalPackageReference Include="CSharpIsNullAnalyzer" Version="0.1.329" />
<GlobalPackageReference Include="DotNetAnalyzers.DocumentationAnalyzers" Version="1.0.0-beta.59" />
<GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.119" />
<GlobalPackageReference Include="Nullable" Version="1.3.1" />
<GlobalPackageReference Include="StyleCop.Analyzers.Unstable" Version="1.2.0.435" />
</ItemGroup>
<ItemGroup>
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Internal.MicroBuild.VisualStudio" Version="$(MicroBuildVersion)" />
</ItemGroup>
</Project>

41
SECURITY.md Normal file
Просмотреть файл

@ -0,0 +1,41 @@
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
## Security
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.**
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/msrc/pgp-key-msrc).
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
* Full paths of source file(s) related to the manifestation of the issue
* The location of the affected source code (tag/branch/commit or direct URL)
* Any special configuration required to reproduce the issue
* Step-by-step instructions to reproduce the issue
* Proof-of-concept or exploit code (if possible)
* Impact of the issue, including how an attacker might exploit the issue
This information will help us triage your report more quickly.
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
## Preferred Languages
We prefer all communications to be in English.
## Policy
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/msrc/cvd).
<!-- END MICROSOFT SECURITY.MD BLOCK -->

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

@ -11,21 +11,27 @@ trigger:
- '*.md'
- .vscode/
- .github/
- azure-pipelines/release.yml
parameters:
- name: includeMacOS
displayName: Build on macOS
type: boolean
default: false # macOS is often bogged down in Azure Pipelines
- name: RunTests
displayName: Run tests
type: boolean
default: true
variables:
TreatWarningsAsErrors: true
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
BuildConfiguration: Release
codecov_token: 1c079a51-729f-4e18-9792-2a75f2e074e0
NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages
NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages/
jobs:
- template: azure-pipelines/build.yml
parameters:
includeMacOS: ${{ parameters.includeMacOS }}
RunTests: ${{ parameters.RunTests }}

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

@ -0,0 +1,220 @@
#Requires -PSEdition Core -Version 7
<#
.SYNOPSIS
Submits a source archival request for this repo.
.PARAMETER Requester
The alias for the user requesting this backup.
.PARAMETER ManagerAlias
The alias of the manager that owns the repo.
.PARAMETER TeamAlias
The alias of the team that owns the repo.
.PARAMETER BusinessGroupName
A human-readable title for your team or business group.
.PARAMETER ProductionType
.PARAMETER ReleaseType
The type of release being backed up.
.PARAMETER ReleaseDate
The date of the release of your software. Defaults to today.
.PARAMETER OwnerAlias
The alias of the owner.
.PARAMETER OS
.PARAMETER ProductLanguage
One or more languages.
.PARAMETER Notes
Any notes to record with the backup.
.PARAMETER FileCollection
One or more collections to archive.
.PARAMETER ProductName
The name of the product. This will default to the repository name.
.PARAMETER RepoUrl
The URL to the repository. This will default to the repository containing this script.
.PARAMETER BackupType
The kind of backup to be performed.
.PARAMETER ServerPath
The UNC path to the server to be backed up (if applicable).
.PARAMETER SourceCodeArchivalUri
The URI to POST the source code archival request to.
This value will typically come automatically by a variable group associated with your pipeline.
You can also look it up at https://dpsrequestforms.azurewebsites.net/#/help -> SCA Request Help -> SCA API Help -> Description
#>
[CmdletBinding(SupportsShouldProcess = $true, PositionalBinding = $false)]
param (
[Parameter()]
[string]$Requester,
[Parameter(Mandatory = $true)]
[string]$ManagerAlias,
[Parameter(Mandatory = $true)]
[string]$TeamAlias,
[Parameter(Mandatory = $true)]
[string]$BusinessGroupName,
[Parameter()]
[string]$ProductionType = 'Visual Studio',
[Parameter()]
[string]$ReleaseType = 'RTW',
[Parameter()]
[DateTime]$ReleaseDate = [DateTime]::Today,
[Parameter()]
[string]$OwnerAlias,
[Parameter()]
[ValidateSet('64-Bit Win', '32-Bit Win', 'Linux', 'Mac', '64-Bit ARM', '32-Bit ARM')]
[string[]]$OS = @('64-Bit Win'),
[Parameter(Mandatory = $true)]
[ValidateSet('English', 'Chinese Simplified', 'Chinese Traditional', 'Czech', 'French', 'German', 'Italian', 'Japanese', 'Korean', 'Polish', 'Portuguese', 'Russian', 'Spanish', 'Turkish')]
[string[]]$ProductLanguage,
[Parameter()]
[string]$Notes = '',
[Parameter()]
[ValidateSet('Binaries', 'Localization', 'Source Code')]
[string[]]$FileCollection = @('Source Code'),
[Parameter()]
[string]$ProductName,
[Parameter()]
[Uri]$RepoUrl,
[Parameter()]
[ValidateSet('Server Path', 'Code Repo(Git URL/AzureDevOps)', 'Git', 'Azure Storage Account')]
[string]$BackupType = 'Code Repo(Git URL/AzureDevOps)',
[Parameter()]
[string]$ServerPath = '',
[Parameter()]
[Uri]$SourceCodeArchivalUri = $env:SOURCECODEARCHIVALURI
)
function Invoke-Git() {
# Make sure we invoke git from within the repo.
Push-Location $PSScriptRoot
try {
return (git $args)
}
finally {
Pop-Location
}
}
if (!$ProductName) {
if ($env:BUILD_REPOSITORY_NAME) {
Write-Verbose 'Using $env:BUILD_REPOSITORY_NAME for ProductName.' # single quotes are intentional so user sees the name of env var.
$ProductName = $env:BUILD_REPOSITORY_NAME
}
else {
$originUrl = [Uri](Invoke-Git remote get-url origin)
if ($originUrl) {
$lastPathSegment = $originUrl.Segments[$originUrl.Segments.Length - 1]
if ($lastPathSegment.EndsWith('.git')) {
$lastPathSegment = $lastPathSegment.Substring(0, $lastPathSegment.Length - '.git'.Length)
}
Write-Verbose 'Using origin remote URL to derive ProductName.'
$ProductName = $lastPathSegment
}
}
if (!$ProductName) {
Write-Error "Unable to determine default value for -ProductName."
}
}
if (!$OwnerAlias) {
if ($env:BUILD_REQUESTEDFOREMAIL) {
Write-Verbose 'Using $env:BUILD_REQUESTEDFOREMAIL and slicing to just the alias for OwnerAlias.'
$OwnerAlias = ($env:BUILD_REQUESTEDFOREMAIL -split '@')[0]
}
else {
Write-Verbose 'Using $env:USERNAME for OwnerAlias.'
$OwnerAlias = $env:USERNAME
}
if (!$OwnerAlias) {
Write-Error "Unable to determine default value for -OwnerAlias."
}
}
if (!$Requester) {
if ($env:BUILD_REQUESTEDFOREMAIL) {
Write-Verbose 'Using $env:BUILD_REQUESTEDFOREMAIL and slicing to just the alias for Requester.'
$Requester = ($env:BUILD_REQUESTEDFOREMAIL -split '@')[0]
}
else {
Write-Verbose 'Using $env:USERNAME for Requester.'
$Requester = $env:USERNAME
}
if (!$Requester) {
Write-Error "Unable to determine default value for -Requester."
}
}
if (!$RepoUrl) {
$RepoUrl = $env:BUILD_REPOSITORY_URI
if (!$RepoUrl) {
$originUrl = [Uri](Invoke-Git remote get-url origin)
if ($originUrl) {
Write-Verbose 'Using git origin remote url for GitURL.'
$RepoUrl = $originUrl
}
if (!$RepoUrl) {
Write-Error "Unable to determine default value for -RepoUrl."
}
}
}
Push-Location $PSScriptRoot
$versionsObj = & (& "$PSScriptRoot/Get-nbgv.ps1") get-version -f json | ConvertFrom-Json
Pop-Location
$ReleaseDateString = $ReleaseDate.ToShortDateString()
$Version = $versionsObj.Version
$BackupSize = Get-ChildItem $PSScriptRoot\..\.git -Recurse -File | Measure-Object -Property Length -Sum
$DataSizeMB = [int]($BackupSize.Sum / 1mb)
$FileCount = $BackupSize.Count
$Request = @{
"Requester" = $Requester
"Manager" = $ManagerAlias
"TeamAlias" = $TeamAlias
"AdditionalContacts" = $AdditionalContacts
"BusinessGroupName" = $BusinessGroupName
"ProductName" = $ProductName
"Version" = $Version
"ProductionType" = $ProductionType
"ReleaseType" = $ReleaseType
"ReleaseDateString" = $ReleaseDateString
"OS" = [string]::Join(',', $OS)
"ProductLanguage" = [string]::Join(',', $ProductLanguage)
"FileCollection" = [string]::Join(',', $FileCollection)
"OwnerAlias" = $OwnerAlias
"Notes" = $Notes.Trim()
"CustomerProvidedDataSizeMB" = $DataSizeMB
"CustomerProvidedFileCount" = $FileCount
"BackupType" = $BackupType
"ServerPath" = $ServerPath
"AzureStorageAccount" = $AzureStorageAccount
"AzureStorageContainer" = $AzureStorageContainer
"GitURL" = $RepoUrl
}
$RequestJson = ConvertTo-Json $Request
Write-Host "SCA request:`n$RequestJson"
if ($PSCmdlet.ShouldProcess('source archival request', 'post')) {
if (!$SourceCodeArchivalUri) {
Write-Error "Unable to post request without -SourceCodeArchivalUri parameter."
exit 1
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$Response = Invoke-WebRequest -Uri $SourceCodeArchivalUri -Method POST -Body $RequestJson -ContentType "application/json" -UseBasicParsing -SkipHttpErrorCheck
Write-Host "Status Code : " -NoNewline
$responseContent = ConvertFrom-Json ($Response.Content)
if ($Response.StatusCode -eq 200) {
Write-Host $Response.StatusCode -ForegroundColor Green
Write-Host "Ticket ID : " -NoNewline
Write-Host $responseContent
}
else {
$responseContent = ConvertFrom-Json $Response.Content
Write-Host $Response.StatusCode -ForegroundColor Red
Write-Host "Message : $($responseContent.message)"
}
} elseif ($SourceCodeArchivalUri) {
Write-Host "Would have posted to $SourceCodeArchivalUri"
}

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

@ -8,36 +8,35 @@
.PARAMETER OutputPath
The path of the output PDB to write.
#>
#Function Convert-PortableToWindowsPDB() {
Param(
[Parameter(Mandatory=$true,Position=0)]
[string]$DllPath,
[Parameter()]
[string]$PdbPath,
[Parameter(Mandatory=$true,Position=1)]
[string]$OutputPath
)
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,Position=0)]
[string]$DllPath,
[Parameter()]
[string]$PdbPath,
[Parameter(Mandatory=$true,Position=1)]
[string]$OutputPath
)
if ($IsMacOS -or $IsLinux) {
Write-Error "This script only works on Windows"
return
}
if ($IsMacOS -or $IsLinux) {
Write-Error "This script only works on Windows"
return
}
$version = '1.1.0-beta2-21101-01'
$baseDir = "$PSScriptRoot/../obj/tools"
$pdb2pdbpath = "$baseDir/Microsoft.DiaSymReader.Pdb2Pdb.$version/tools/Pdb2Pdb.exe"
if (-not (Test-Path $pdb2pdbpath)) {
if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null }
$baseDir = (Resolve-Path $baseDir).Path # Normalize it
Write-Verbose "& (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json | Out-Null"
& (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json | Out-Null
}
$version = '1.1.0-beta2-21101-01'
$baseDir = "$PSScriptRoot/../obj/tools"
$pdb2pdbpath = "$baseDir/Microsoft.DiaSymReader.Pdb2Pdb.$version/tools/Pdb2Pdb.exe"
if (-not (Test-Path $pdb2pdbpath)) {
if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null }
$baseDir = (Resolve-Path $baseDir).Path # Normalize it
Write-Verbose "& (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json | Out-Null"
& (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json | Out-Null
}
$args = $DllPath,'/out',$OutputPath,'/nowarn','0021'
if ($PdbPath) {
$args += '/pdb',$PdbPath
}
$args = $DllPath,'/out',$OutputPath,'/nowarn','0021'
if ($PdbPath) {
$args += '/pdb',$PdbPath
}
Write-Verbose "$pdb2pdbpath $args"
& $pdb2pdbpath $args
#}
Write-Verbose "$pdb2pdbpath $args"
& $pdb2pdbpath $args

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

@ -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

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

@ -0,0 +1,26 @@
<#
.SYNOPSIS
Look up the pull request URL of the insertion PR.
#>
$stagingFolder = $env:BUILD_STAGINGDIRECTORY
if (!$stagingFolder) {
$stagingFolder = $env:SYSTEM_DEFAULTWORKINGDIRECTORY
if (!$stagingFolder) {
Write-Error "This script must be run in an Azure Pipeline."
exit 1
}
}
$markdownFolder = Join-Path $stagingFolder (Join-Path 'MicroBuild' 'Output')
$markdownFile = Join-Path $markdownFolder 'PullRequestUrl.md'
if (!(Test-Path $markdownFile)) {
Write-Error "This script should be run after the MicroBuildInsertVsPayload task."
exit 2
}
$insertionPRUrl = Get-Content $markdownFile
if (!($insertionPRUrl -match 'https:.+?/pullrequest/(\d+)')) {
Write-Error "Failed to parse pull request URL: $insertionPRUrl"
exit 3
}
$Matches[1]

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

@ -18,7 +18,7 @@ Write-Progress -Activity $ActivityName -CurrentOperation "Discovery PDB files"
$PDBs = Get-ChildItem -rec "$Path/*.pdb"
# Filter PDBs to product OR test related.
$testregex = "unittest|tests"
$testregex = "unittest|tests|\.test\."
Write-Progress -Activity $ActivityName -CurrentOperation "De-duplicating symbols"
$PDBsByHash = @{}
@ -49,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 $_.FullName
if ($BinaryImagePath) {
Write-Output $BinaryImagePath
Write-Output $_.FullName
}
}

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

@ -11,6 +11,8 @@
The directory to install the package to. By default, it uses the Packages folder at the root of the repo.
.PARAMETER ConfigFile
The nuget.config file to use. By default, it uses :/nuget.config.
.OUTPUTS
System.String. The path to the installed package.
#>
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Low')]
Param(
@ -45,6 +47,9 @@ try {
$p = Start-Process $nugetPath $nugetArgs -NoNewWindow -Wait -PassThru
if ($p.ExitCode -ne 0) { throw }
}
# Provide the path to the installed package directory to our caller.
Write-Output (Get-ChildItem "$PackagesDir\$PackageId.*")[0].FullName
} finally {
Pop-Location
}

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

@ -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."
}

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

@ -0,0 +1,57 @@
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[Parameter(Mandatory=$true)]
$AccessToken,
[Parameter(Mandatory=$true)]
$Markdown,
[ValidateSet('Active','ByDesign','Closed','Fixed','Pending','Unknown','WontFix')]
$CommentState='Active'
)
# See https://docs.microsoft.com/en-us/dotnet/api/microsoft.teamfoundation.sourcecontrol.webapi.commentthreadstatus?view=azure-devops-dotnet
if ($CommentState -eq 'Active') {
$StatusCode = 1
} elseif ($CommentState -eq 'ByDesign') {
$StatusCode = 5
} elseif ($CommentState -eq 'Closed') {
$StatusCode = 4
} elseif ($CommentState -eq 'Fixed') {
$StatusCode = 2
} elseif ($CommentState -eq 'Pending') {
$StatusCode = 6
} elseif ($CommentState -eq 'Unknown') {
$StatusCode = 0
} elseif ($CommentState -eq 'WontFix') {
$StatusCode = 3
}
# Build the JSON body up
$body = ConvertTo-Json @{
comments = @(@{
parentCommentId = 0
content = $Markdown
commentType = 1
})
status = $StatusCode
}
Write-Verbose "Posting JSON payload: `n$Body"
# Post the message to the Pull Request
# https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull%20request%20threads?view=azure-devops-rest-5.1
$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_NAME)/pullRequests/$($env:SYSTEM_PULLREQUEST_PULLREQUESTID)/threads?api-version=5.1"
if ($PSCmdlet.ShouldProcess($url, 'Post comment via REST call')) {
try {
if (!$env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI) {
Write-Error "Posting to the pull request requires that the script is running in an Azure Pipelines context."
exit 1
}
Write-Host "Posting PR comment to: $url"
Invoke-RestMethod -Uri $url -Method POST -Headers @{Authorization = "Bearer $AccessToken"} -Body $Body -ContentType application/json
}
catch {
Write-Error $_
Write-Error $_.Exception.Message
exit 2
}
}

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

@ -14,19 +14,24 @@ Get-ChildItem "$ArtifactStagingFolder\*.pdb" -Recurse |% {
$BinaryImagePath = $dllPath
} elseif (Test-Path $exePath) {
$BinaryImagePath = $exePath
} else {
Write-Warning "`"$_`" found with no matching binary file."
$BinaryImagePath = $null
}
# Convert the PDB to legacy Windows PDBs
Write-Host "Converting PDB for $_" -ForegroundColor DarkGray
$WindowsPdbDir = "$($_.Directory.FullName)\$WindowsPdbSubDirName"
if (!(Test-Path $WindowsPdbDir)) { mkdir $WindowsPdbDir | Out-Null }
$legacyPdbPath = "$WindowsPdbDir\$($_.BaseName).pdb"
& "$PSScriptRoot\Convert-PDB.ps1" -DllPath $BinaryImagePath -PdbPath $_ -OutputPath $legacyPdbPath
if ($LASTEXITCODE -ne 0) {
Write-Warning "PDB conversion of `"$_`" failed."
}
if ($BinaryImagePath) {
# Convert the PDB to legacy Windows PDBs
Write-Host "Converting PDB for $_" -ForegroundColor DarkGray
$WindowsPdbDir = "$($_.Directory.FullName)\$WindowsPdbSubDirName"
if (!(Test-Path $WindowsPdbDir)) { mkdir $WindowsPdbDir | Out-Null }
$legacyPdbPath = "$WindowsPdbDir\$($_.BaseName).pdb"
& "$PSScriptRoot\Convert-PDB.ps1" -DllPath $BinaryImagePath -PdbPath $_ -OutputPath $legacyPdbPath
if ($LASTEXITCODE -ne 0) {
Write-Warning "PDB conversion of `"$_`" failed."
}
Move-Item $legacyPdbPath $_ -Force
Move-Item $legacyPdbPath $_ -Force
}
}
Write-Host "##vso[artifact.upload containerfolder=symbols-legacy;artifactname=symbols-legacy;]$ArtifactStagingFolder"

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

@ -0,0 +1,52 @@
trigger: none # We only want to trigger manually or based on resources
pr: none
# Source archival requirements come from a compliance tenet. Review a sample task here: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1550985
# Source code should be archived within 30 days of the release date, and at least every quarter if your product is releasing more than once every 6 months.
# If your sources on GitHub are public open source project, then using GitHub Public Archive is sufficient.
schedules:
- cron: "13 13 13 */3 *" # Every three months
displayName: Periodic source archival
branches:
include:
- main
parameters:
- name: notes
displayName: Notes to include in the SCA request
type: string
default: ' ' # optional parameters require a non-empty default.
- name: whatif
displayName: Only simulate the request
type: boolean
default: false
variables:
- group: VS Core team # Expected to provide ManagerAlias, SourceCodeArchivalUri
pool:
name: AzurePipelines-EO
vmImage: AzurePipelinesUbuntu20.04compliant
steps:
- checkout: self
clean: true
fetchDepth: 0
- powershell: tools/Install-DotNetSdk.ps1
displayName: ⚙ Install .NET SDK
- powershell: azure-pipelines/variables/_pipelines.ps1
failOnStderr: true
displayName: ⚙ Set pipeline variables based on source
- powershell: >
$TeamAlias = '$(TeamEmail)'.Substring(0, '$(TeamEmail)'.IndexOf('@'))
azure-pipelines/Archive-SourceCode.ps1
-ManagerAlias '$(ManagerAlias)'
-TeamAlias $TeamAlias
-BusinessGroupName '$(BusinessGroupName)'
-ProductName '$(SymbolsFeatureName)'
-ProductLanguage English
-Notes '${{ parameters.notes }}'
-Verbose
-WhatIf:$${{ parameters.whatif }}
displayName: 🗃️ Submit archival request

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

@ -1,13 +1,15 @@
# This artifact captures everything needed to insert into VS (NuGet packages, insertion metadata, etc.)
<#
.PARAMETER SbomNotRequired
Indicates that returning the artifacts available is preferable to nothing at all when the SBOM has not yet been generated.
#>
[CmdletBinding()]
Param (
[switch]$SbomNotRequired
)
if ($IsMacOS -or $IsLinux) {
# We only package up for insertions on Windows agents since they are where optprof can happen.
Write-Verbose "Skipping VSInsertion artifact since we're not on Windows."
return @{}
}
$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..")
$BuildConfiguration = $env:BUILDCONFIGURATION
if (!$BuildConfiguration) {
@ -16,10 +18,10 @@ if (!$BuildConfiguration) {
$PackagesRoot = "$RepoRoot/bin/Packages/$BuildConfiguration/NuGet"
# This artifact is not ready if we're running on the devdiv AzDO account and we don't have an SBOM yet.
if ($env:SYSTEM_COLLECTIONID -eq '011b8bdf-6d56-4f87-be0d-0092136884d9' -and -not (Test-Path $PackagesRoot/_manifest) -and -not $SbomNotRequired) { return @{} }
if (!(Test-Path $PackagesRoot)) { return @{} }
if (!(Test-Path $PackagesRoot)) {
Write-Warning "Skipping because packages haven't been built yet."
return @{}
}
@{
"$PackagesRoot" = (Get-ChildItem $PackagesRoot -Recurse)

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

@ -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,15 +29,16 @@ 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
Write-Verbose "Collecting file list for artifact $($_.BaseName)"
$fileGroups = & $_
if ($fileGroups) {
$fileGroups.GetEnumerator() | % {
@ -65,6 +67,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,7 +1,11 @@
# 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
)
@ -21,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 {
@ -43,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,10 +1,11 @@
$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}`""
$reports = Get-ChildItem "$RepoRoot/bin/coverage.*cobertura.xml" -Recurse
$reports |% {
$coverageFiles |% {
$content = Get-Content -Path $_ |% { $_ -Replace [regex]::Escape($env:SYSTEM_DEFAULTWORKINGDIRECTORY), "{reporoot}" }
Set-Content -Path $_ -Value $content -Encoding UTF8
}
@ -16,7 +17,7 @@ if (!((Test-Path $RepoRoot\bin) -and (Test-Path $RepoRoot\obj))) { return }
@{
$RepoRoot = (
@(Get-ChildItem "$RepoRoot\bin\coverage.*cobertura.xml" -Recurse) +
$coverageFiles +
(Get-ChildItem "$RepoRoot\obj\*.cs" -Recurse)
);
}

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

@ -1,16 +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)\*_crashdump.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) {

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

@ -4,19 +4,27 @@ parameters:
default:
vmImage: windows-2022
- name: includeMacOS
- name: RunTests
type: boolean
default: true
- name: EnableCompliance
type: boolean
default: true
- name: EnableAPIScan
type: boolean
default: false
default: true
jobs:
- job: Windows
pool: ${{ parameters.windowsPool }}
timeoutInMinutes: 180 # Give plenty of time due to real signing
variables:
- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
# https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/25351/APIScan-step-by-step-guide-to-setting-up-a-Pipeline
- group: VSCloudServices-APIScan
- group: VSCloudServices-APIScan # Expected to provide ApiScanClientId, ApiScanSecret, ApiScanTenant
steps:
- checkout: self
fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
clean: true
- ${{ if eq(variables['Build.Reason'], 'Schedule') }}:
@ -25,16 +33,19 @@ jobs:
- template: install-dependencies.yml
- powershell: '& (./azure-pipelines/Get-nbgv.ps1) cloud -ca'
displayName: Set build number
displayName: Set build number
- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
- template: microbuild.before.yml
- template: dotnet.yml
parameters:
RunTests: ${{ parameters.RunTests }}
- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
- template: microbuild.after.yml
parameters:
EnableCompliance: ${{ parameters.EnableCompliance }}
EnableAPIScan: ${{ parameters.EnableAPIScan }}
# Repeat this step to scoop up any artifacts that would only be collected after running microbuild.after.yml
- powershell: azure-pipelines/artifacts/_pipelines.ps1 -ArtifactNameSuffix "-$(Agent.JobName)"
@ -47,19 +58,25 @@ jobs:
vmImage: Ubuntu 20.04
steps:
- checkout: self
fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
clean: true
- template: install-dependencies.yml
- template: dotnet.yml
parameters:
RunTests: ${{ parameters.RunTests }}
- job: macOS
condition: ${{ parameters.includeMacOS }}
pool:
vmImage: macOS-10.15
vmImage: macOS-12
steps:
- checkout: self
fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
clean: true
- template: install-dependencies.yml
- template: dotnet.yml
parameters:
RunTests: ${{ parameters.RunTests }}
- job: WrapUp
dependsOn:
@ -70,6 +87,7 @@ jobs:
condition: succeededOrFailed()
steps:
- checkout: self
fetchDepth: 0 # avoid shallow clone so nbgv can do its work.
clean: true
- template: install-dependencies.yml
parameters:
@ -77,6 +95,7 @@ jobs:
- template: publish-symbols.yml
parameters:
includeMacOS: ${{ parameters.includeMacOS }}
- template: publish-codecoverage.yml
parameters:
includeMacOS: ${{ parameters.includeMacOS }}
- ${{ if parameters.RunTests }}:
- template: publish-codecoverage.yml
parameters:
includeMacOS: ${{ parameters.includeMacOS }}

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

@ -1,24 +1,60 @@
#!/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]$PublishResults,
[switch]$x86,
[string]$dotnet32
)
$RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path
$ArtifactStagingFolder = & "$PSScriptRoot/Get-ArtifactsStagingDirectory.ps1"
dotnet test $RepoRoot `
$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" `
-p:CollectCoverage=true `
--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
--logger trx `
$unknownCounter = 0
Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx |% {
@ -26,16 +62,20 @@ Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx |% {
if ($PublishResults) {
$x = [xml](Get-Content -Path $_)
$storage = $x.TestRun.TestDefinitions.GetElementsByTagName('UnitTest')[0].storage -replace '\\','/'
if ($storage -match '/(?<tfm>net[^/]+)/(?:(?<rid>[^/]+)/)?(?<lib>[^/]+)\.dll$') {
$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), $Agent)"
$runTitle = "$($matches.lib) ($($matches.tfm)$x86RunTitleSuffix, $Agent)"
}
} else {
$unknownCounter += 1;
$runTitle = "unknown$unknownCounter ($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,23 +1,30 @@
parameters:
RunTests:
steps:
- script: dotnet build -t:build,pack --no-restore -c $(BuildConfiguration) /bl:"$(Build.ArtifactStagingDirectory)/build_logs/build.binlog"
displayName: dotnet build
displayName: 🛠 dotnet build
- powershell: azure-pipelines/dotnet-test-cloud.ps1 -Configuration $(BuildConfiguration) -Agent $(Agent.JobName) -PublishResults
displayName: dotnet test
displayName: 🧪 dotnet test
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()
- bash: bash <(curl -s https://codecov.io/bash)
displayName: Publish code coverage results to codecov.io
condition: ne(variables['codecov_token'], '')
timeoutInMinutes: 3
continueOnError: true
- ${{ 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,9 +3,11 @@ parameters:
steps:
- task: NuGetAuthenticate@0
displayName: Authenticate NuGet feeds
- task: NuGetAuthenticate@1
displayName: 🔏 Authenticate NuGet feeds
inputs:
${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}:
nuGetServiceConnections: azure-public/msft_consumption
forceReinstallCredentialProvider: true
- powershell: |
@ -17,9 +19,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

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

@ -1,29 +1,20 @@
parameters:
- name: EnableAPIScan
type: boolean
EnableCompliance:
EnableAPIScan:
steps:
- task: MicroBuildCodesignVerify@3
displayName: Verify Signed Files
displayName: 🔍 Verify Signed Files
inputs:
TargetFolders: |
$(Build.SourcesDirectory)/bin/Packages/$(BuildConfiguration)/NuGet
- task: MicroBuildCleanup@1
condition: succeededOrFailed()
displayName: MicroBuild Cleanup
- task: ManifestGeneratorTask@0
displayName: Software Bill of Materials generation
inputs:
BuildDropPath: $(System.DefaultWorkingDirectory)/bin/Microsoft.VisualStudio.Validation/$(BuildConfiguration)
BuildComponentPath: $(System.DefaultWorkingDirectory)/obj/src/Microsoft.VisualStudio.Validation
- powershell: Copy-Item -Recurse "$(System.DefaultWorkingDirectory)/bin/Microsoft.VisualStudio.Validation/$(BuildConfiguration)/_manifest" "$(System.DefaultWorkingDirectory)/bin/Packages/$(BuildConfiguration)/NuGet"
displayName: Publish Software Bill of Materials
displayName: ⚙️ MicroBuild Cleanup
- task: Ref12Analyze@0
displayName: Ref12 (Codex) Analyze
displayName: 📑 Ref12 (Codex) Analyze
inputs:
codexoutputroot: $(Build.ArtifactStagingDirectory)\Codex
workflowArguments: |
@ -35,6 +26,7 @@ steps:
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'), ne(variables['Build.Reason'], 'PullRequest'))
continueOnError: true
- template: secure-development-tools.yml
parameters:
EnableAPIScan: ${{ parameters.EnableAPIScan }}
- ${{ if eq(parameters.EnableCompliance, 'true') }}:
- template: secure-development-tools.yml
parameters:
EnableAPIScan: ${{ parameters.EnableAPIScan }}

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

@ -1,9 +1,9 @@
steps:
- task: ComponentGovernanceComponentDetection@0
displayName: Component Detection
displayName: 🔍 Component Detection
- task: notice@0
displayName: Generate NOTICE file
displayName: 🛠️ Generate NOTICE file
inputs:
outputfile: $(System.DefaultWorkingDirectory)/obj/NOTICE
outputformat: text
@ -11,9 +11,13 @@ steps:
- task: MicroBuildSigningPlugin@3
inputs:
signType: $(SignType)
displayName: Install MicroBuild Signing Plugin
zipSources: false
displayName: 🔧 Install MicroBuild Signing Plugin
- task: MicroBuildSbomPlugin@1
displayName: 🔧 Install MicroBuild Sbom Plugin
- task: MicroBuildLocalizationPlugin@3
inputs:
languages: $(LocLanguages)
displayName: Install MicroBuild Localization Plugin
displayName: 🔧 Install MicroBuild Localization Plugin

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

@ -31,8 +31,16 @@ parameters:
displayName: Build on macOS
type: boolean
default: false # macOS is often bogged down in Azure Pipelines
- name: RunTests
displayName: Run tests
type: boolean
default: true
- name: EnableCompliance
displayName: Run Compliance Tools
type: boolean
default: true
- name: EnableAPIScan
displayName: Run APIScan
displayName: Include APIScan with Compliance tools
type: boolean
default: true
@ -45,67 +53,16 @@ stages:
BuildConfiguration: Release
NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages
SignTypeSelection: ${{ parameters.SignTypeSelection }}
Packaging.EnableSBOMSigning: true
Packaging.EnableSBOMSigning: false
Codeql.Enabled: true
jobs:
- template: build.yml
parameters:
EnableCompliance: ${{ parameters.EnableCompliance }}
EnableAPIScan: ${{ parameters.EnableAPIScan }}
windowsPool: VSEngSS-MicroBuild2022-1ES
includeMacOS: ${{ parameters.includeMacOS }}
RunTests: ${{ parameters.RunTests }}
- stage: symbol_archive
displayName: Symbol archival
condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real'))
jobs:
- job: archive
pool: VSEng-ReleasePool-1ES
steps:
- checkout: none
- download: current
artifact: Variables-Windows
displayName: Download Variables-Windows artifact
- task: PowerShell@2
displayName: Set VSTS variables based on artifacts
inputs:
targetType: filePath
filePath: $(Pipeline.Workspace)/Variables-Windows/_pipelines.ps1
- download: current
artifact: symbols-legacy
displayName: Download symbols-legacy artifact
- task: MicroBuildArchiveSymbols@1
displayName: Archive symbols to Symweb
inputs:
SymbolsFeatureName: $(SymbolsFeatureName)
SymbolsSymwebProject: VS
SymbolsUncPath: \\cpvsbuild\drops\$(TeamName)\$(Build.DefinitionName)\$(Build.SourceBranchName)\$(Build.BuildId)\Symbols.Archival
SymbolsEmailContacts: vsidemicrobuild
SymbolsAgentPath: $(Pipeline.Workspace)/symbols-legacy
- task: MicroBuildCleanup@1
displayName: Send Telemetry
- stage: azure_public_vssdk_feed
displayName: azure-public/vssdk feed
condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real'))
jobs:
- job: push
pool:
name: AzurePipelines-EO
vmImage: AzurePipelinesUbuntu20.04compliant
steps:
- checkout: none
- download: current
artifact: deployables-Windows
displayName: Download deployables-Windows artifact
- task: UseDotNet@2
displayName: Install .NET SDK
inputs:
packageType: sdk
version: 6.x
- task: NuGetAuthenticate@0
displayName: Authenticate NuGet feeds
inputs:
nuGetServiceConnections: azure-public/vssdk
forceReinstallCredentialProvider: true
- script: dotnet nuget push $(Pipeline.Workspace)/deployables-Windows/NuGet/*.nupkg -s https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json --api-key azdo --skip-duplicate
displayName: Push nuget packages
- template: prepare-insertion-stages.yml

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

@ -0,0 +1,56 @@
stages:
- stage: symbol_archive
displayName: Symbol archival
condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real'))
jobs:
- job: archive
pool: VSEng-ReleasePool-1ES
steps:
- checkout: none
- download: current
artifact: Variables-Windows
displayName: Download Variables-Windows artifact
- task: PowerShell@2
displayName: Set pipeline variables based on artifacts
inputs:
targetType: filePath
filePath: $(Pipeline.Workspace)/Variables-Windows/_pipelines.ps1
- download: current
artifact: symbols-legacy
displayName: Download symbols-legacy artifact
- task: MicroBuildArchiveSymbols@1
displayName: Archive symbols to Symweb
inputs:
SymbolsFeatureName: $(SymbolsFeatureName)
SymbolsSymwebProject: VS
SymbolsUncPath: \\cpvsbuild\drops\$(TeamName)\$(Build.DefinitionName)\$(Build.SourceBranchName)\$(Build.BuildId)\Symbols.Archival
SymbolsEmailContacts: vsidemicrobuild
SymbolsAgentPath: $(Pipeline.Workspace)/symbols-legacy
- task: MicroBuildCleanup@1
displayName: Send Telemetry
- stage: azure_public_vssdk_feed
displayName: azure-public/vssdk feed
condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real'))
jobs:
- job: push
pool:
name: AzurePipelines-EO
vmImage: AzurePipelinesUbuntu20.04compliant
steps:
- checkout: none
- download: current
artifact: deployables-Windows
displayName: Download deployables-Windows artifact
- task: UseDotNet@2
displayName: Install .NET SDK
inputs:
packageType: sdk
version: 6.x
- task: NuGetAuthenticate@1
displayName: Authenticate NuGet feeds
inputs:
nuGetServiceConnections: azure-public/vssdk
forceReinstallCredentialProvider: true
- script: dotnet nuget push $(Pipeline.Workspace)/deployables-Windows/NuGet/*.nupkg -s https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json --api-key azdo --skip-duplicate
displayName: Push nuget packages

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

@ -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
}

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

@ -4,32 +4,22 @@ parameters:
steps:
- download: current
artifact: coverageResults-Windows
displayName: Download Windows code coverage results
displayName: 🔻 Download Windows code coverage results
continueOnError: true
- download: current
artifact: coverageResults-Linux
displayName: Download Linux code coverage results
displayName: 🔻 Download Linux code coverage results
continueOnError: true
- download: current
artifact: coverageResults-macOS
displayName: Download macOS code coverage results
displayName: 🔻 Download macOS code coverage results
continueOnError: true
condition: ${{ parameters.includeMacOS }}
- powershell: |
dotnet tool install --tool-path obj dotnet-reportgenerator-globaltool --version 4.8.5 --configfile azure-pipelines/justnugetorg.nuget.config
Copy-Item -Recurse $(Pipeline.Workspace)/coverageResults-Windows/obj/* $(System.DefaultWorkingDirectory)/obj
Write-Host 'Substituting {reporoot} with $(System.DefaultWorkingDirectory)'
$reports = Get-ChildItem -Recurse '$(Pipeline.Workspace)/coverage.*cobertura.xml'
$reports |% {
$content = Get-Content -Path $_ |% { $_.Replace('{reporoot}', '$(System.DefaultWorkingDirectory)') }
Set-Content -Path $_ -Value $content -Encoding UTF8
}
$Inputs = [string]::join(';', ($reports |% { Resolve-Path -relative $_ }))
obj/reportgenerator -reports:"$Inputs" -targetdir:coveragereport -reporttypes:Cobertura
displayName: Merge coverage
condition: and(succeeded(), ${{ parameters.includeMacOS }})
- 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
displayName: 📢 Publish code coverage results to Azure DevOps
inputs:
codeCoverageTool: cobertura
summaryFileLocation: 'coveragereport/Cobertura.xml'
summaryFileLocation: coveragereport/merged.cobertura.xml
failIfCoverageEmpty: true

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

@ -6,19 +6,19 @@ steps:
inputs:
artifact: symbols-Windows
path: $(Pipeline.Workspace)/symbols/Windows
displayName: Download Windows symbols
displayName: 🔻 Download Windows symbols
continueOnError: true
- task: DownloadPipelineArtifact@2
inputs:
artifact: symbols-Linux
path: $(Pipeline.Workspace)/symbols/Linux
displayName: Download Linux symbols
displayName: 🔻 Download Linux symbols
continueOnError: true
- task: DownloadPipelineArtifact@2
inputs:
artifact: symbols-macOS
path: $(Pipeline.Workspace)/symbols/macOS
displayName: Download macOS symbols
displayName: 🔻 Download macOS symbols
continueOnError: true
condition: ${{ parameters.includeMacOS }}
@ -26,19 +26,19 @@ steps:
inputs:
artifact: test_symbols-Windows
path: $(Pipeline.Workspace)/test_symbols/Windows
displayName: Download Windows test symbols
displayName: 🔻 Download Windows test symbols
continueOnError: true
- task: DownloadPipelineArtifact@2
inputs:
artifact: test_symbols-Linux
path: $(Pipeline.Workspace)/test_symbols/Linux
displayName: Download Linux test symbols
displayName: 🔻 Download Linux test symbols
continueOnError: true
- task: DownloadPipelineArtifact@2
inputs:
artifact: test_symbols-macOS
path: $(Pipeline.Workspace)/test_symbols/macOS
displayName: Download macOS test symbols
displayName: 🔻 Download macOS test symbols
continueOnError: true
condition: ${{ parameters.includeMacOS }}
@ -48,7 +48,7 @@ steps:
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
displayName: Publish symbols
displayName: 📢 Publish symbols
- task: PublishSymbols@2
inputs:
@ -56,7 +56,7 @@ steps:
SearchPattern: '**/*.pdb'
IndexSources: false
SymbolServerType: TeamServices
displayName: Publish test symbols
displayName: 📢 Publish test symbols
- powershell: azure-pipelines/Publish-Legacy-Symbols.ps1 -Path $(Pipeline.Workspace)/symbols/Windows
displayName: Publish symbols for symbol archival
displayName: 📢 Publish symbols for symbol archival

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

@ -10,7 +10,7 @@ resources:
- auto-release
variables:
- group: VS SDK feeds
- group: VS SDK feeds # Expected to provide NuGetOrgApiKey
jobs:
- job: release
@ -26,18 +26,18 @@ jobs:
} else {
Write-Host "##vso[task.setvariable variable=IsPrerelease]false"
}
displayName: Set up pipeline
displayName: Set up pipeline
- task: UseDotNet@2
displayName: Install .NET SDK
displayName: Install .NET SDK
inputs:
packageType: sdk
version: 6.x
- download: CI
artifact: deployables-Windows
displayName: Download deployables-Windows artifact
patterns: 'deployables-Windows/*'
displayName: 🔻 Download deployables-Windows artifact
patterns: 'deployables-Windows/NuGet/*'
- task: GitHubRelease@1
displayName: GitHub release (create)
displayName: 📢 GitHub release (create)
inputs:
gitHubConnection: AArnott
repositoryName: $(Build.Repository.Name)
@ -52,9 +52,10 @@ jobs:
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/NuGet/*.nupkg -s https://api.nuget.org/v3/index.json --api-key $(NuGetOrgApiKey) --skip-duplicate
displayName: Push nuget packages
displayName: 📦 Push packages to nuget.org
condition: and(succeeded(), ne(variables['NuGetOrgApiKey'], ''))

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

@ -1,21 +1,23 @@
parameters:
- name: EnableAPIScan
type: boolean
EnableAPIScan:
steps:
- powershell: echo "##vso[build.addbuildtag]compliance"
displayName: 🏷️ Tag run with 'compliance'
- task: CredScan@3
displayName: Run CredScan
displayName: 🔍 Run CredScan
- task: PoliCheck@2
displayName: Run PoliCheck
displayName: 🔍 Run PoliCheck
inputs:
targetType: F
targetArgument: $(System.DefaultWorkingDirectory)
optionsUEPATH: $(System.DefaultWorkingDirectory)\azure-pipelines\PoliCheckExclusions.xml
- task: BinSkim@4
displayName: Run BinSkim
displayName: 🔍 Run BinSkim
inputs:
InputType: Basic
Function: analyze
@ -23,17 +25,18 @@ steps:
AnalyzeTargetGlob: $(BinSkimTargets)
- task: CopyFiles@2
displayName: Collect APIScan inputs
displayName: 🔍 Collect APIScan inputs
inputs:
SourceFolder: $(Build.ArtifactStagingDirectory)/Symbols-$(Agent.JobName)
# Exclude any patterns from the Contents (e.g. `!**/git2*`) that we have symbols for but do not need to run APIScan on.
Contents: |
**
!**/arm64/**
TargetFolder: $(Build.ArtifactStagingDirectory)/APIScanInputs
condition: and(succeeded(), ${{ parameters.EnableAPIScan }}, ne(variables.ApiScanClientId, ''))
- task: APIScan@2
displayName: Run APIScan
displayName: 🔍 Run APIScan
inputs:
softwareFolder: $(Build.ArtifactStagingDirectory)/APIScanInputs
softwareName: $(SymbolsFeatureName)
@ -45,12 +48,12 @@ steps:
AzureServicesAuthConnectionString: runAs=App;AppId=$(ApiScanClientId);TenantId=$(ApiScanTenant);AppKey=$(ApiScanSecret)
- task: SdtReport@2
displayName: Create Security Analysis Report
displayName: 📃 Create Security Analysis Report
inputs:
GdnExportAllTools: true
- task: PublishSecurityAnalysisLogs@3
displayName: Publish Code Analysis Logs
displayName: 📢 Publish Code Analysis Logs
inputs:
ArtifactName: CodeAnalysisLogs
ArtifactType: Container
@ -59,7 +62,7 @@ steps:
ToolLogsNotFoundAction: Standard
- task: PostAnalysis@2
displayName: Break on compliance issues
displayName: 🏋️‍♀️ Break on compliance issues
inputs:
GdnBreakAllTools: true
GdnBreakGdnToolBinSkimSeverity: Warning
@ -71,5 +74,5 @@ steps:
# This is useful when false positives appear so we can copy some of the output into the suppressions file.
- publish: $(Build.ArtifactStagingDirectory)/guardian_failures_as_suppressions
artifact: guardian_failures_as_suppressions
displayName: Publish Guardian failures
displayName: 🔍 Publish Guardian failures
condition: failed()

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

@ -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>

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

@ -0,0 +1 @@
'Visual Studio - VS Core'

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

@ -1,4 +1,4 @@
$InsertedPkgs = (& "$PSScriptRoot\..\artifacts\VSInsertion.ps1" -SbomNotRequired)
$InsertedPkgs = (& "$PSScriptRoot\..\artifacts\VSInsertion.ps1")
$icv=@()
foreach ($kvp in $InsertedPkgs.GetEnumerator()) {

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

@ -1 +1,13 @@
'Andrew Arnott'
# This is a list of AzDO account names or email addresses.
# Add your team DL and/or whoever should be notified of insertion PRs.
$contacts = ,$env:BUILD_REQUESTEDFOREMAIL
$contacts += 'Andrew Arnott'
if (Test-Path "$PSScriptRoot\TeamEmail.ps1") {
$contacts += & "$PSScriptRoot\TeamEmail.ps1"
}
$contacts = $contacts |? { $_ }
if ($contacts) {
[string]::Join(',', $contacts)
}

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

@ -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

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

@ -20,15 +20,15 @@ jobs:
- checkout: none
- powershell: Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)"
displayName: Set pipeline name
- task: NuGetAuthenticate@0
displayName: Authenticate NuGet feeds
inputs:
forceReinstallCredentialProvider: true
- task: UseDotNet@2
displayName: Install .NET SDK
inputs:
packageType: sdk
version: 6.x
- task: NuGetAuthenticate@1
displayName: Authenticate NuGet feeds
inputs:
forceReinstallCredentialProvider: true
- template: release-deployment-prep.yml
- download: CI
artifact: VSInsertion-Windows

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

@ -0,0 +1,84 @@
# This is a top-level pipeline file, which is designed to be added as an optional PR build policy
# so that a VS insertion and all the validation that entails can be done before ever merging the PR
# in its original repo.
trigger: none # We only want to trigger manually or based on resources
pr: none
stages:
- stage: Build
variables:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages
SignTypeSelection: Real
BuildConfiguration: Release
ValidationBuild: true
jobs:
- template: build.yml
parameters:
EnableCompliance: false
EnableAPIScan: false
windowsPool: VSEngSS-MicroBuild2022-1ES
includeMacOS: false
RunTests: false
- template: prepare-insertion-stages.yml
- stage: insertion
displayName: VS insertion
jobs:
- job: insertion
displayName: VS insertion
pool: VSEngSS-MicroBuild2022-1ES
steps:
- checkout: self
clean: true
fetchDepth: 1
- task: UseDotNet@2
displayName: Install .NET SDK
inputs:
packageType: sdk
version: 6.x
- task: NuGetAuthenticate@1
displayName: Authenticate NuGet feeds
inputs:
forceReinstallCredentialProvider: true
- download: current
artifact: Variables-Windows
displayName: Download Variables-Windows artifact
- task: PowerShell@2
displayName: Set pipeline variables based on artifacts
inputs:
targetType: filePath
filePath: $(Pipeline.Workspace)/Variables-Windows/_pipelines.ps1
- download: current
artifact: VSInsertion-Windows
displayName: Download VSInsertion-Windows artifact
- script: dotnet nuget push VSInsertion-windows\*.nupkg -s https://pkgs.dev.azure.com/devdiv/_packaging/VS/nuget/v3/index.json -k azdo --skip-duplicate
displayName: Push CoreXT packages to VS feed
workingDirectory: $(Pipeline.Workspace)
- task: MicroBuildInsertVsPayload@4
displayName: Insert VS Payload
inputs:
TeamName: $(TeamName)
TeamEmail: $(TeamEmail)
InsertionPayloadName: $(Build.Repository.Name) VALIDATION BUILD $(Build.BuildNumber) ($(Build.SourceBranch))
InsertionDescription: |
This PR is for **validation purposes only** for !$(System.PullRequest.PullRequestId). **Do not complete**.
CustomScriptExecutionCommand: src/VSSDK/NuGet/AllowUnstablePackages.ps1
InsertionBuildPolicy: Request Perf DDRITs
InsertionReviewers: $(Build.RequestedForEmail)
AutoCompletePR: false
- powershell: |
$insertionPRId = azure-pipelines/Get-InsertionPRId.ps1
$Markdown = @"
Validation insertion pull request created: !$insertionPRId
Please check status there before proceeding to merge this PR.
Remember to Abandon and (if allowed) to Delete Source Branch on that insertion PR when validation is complete.
"@
azure-pipelines/PostPRMessage.ps1 -AccessToken '$(System.AccessToken)' -Markdown $Markdown -Verbose
displayName: Comment on pull request
condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
- task: MicroBuildCleanup@1
displayName: Send Telemetry

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

@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.200",
"version": "7.0.100-rc.2.22477.23",
"rollForward": "patch",
"allowPrerelease": false
}

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

@ -35,6 +35,8 @@
The environment is configured to build pseudo-loc for JPN only, but may be used to build
all languages with shipping-style loc by using the `/p:loctype=full,loclanguages=vs`
when building.
.PARAMETER Sbom
Install the MicroBuild SBOM plugin.
.PARAMETER AccessToken
An optional access token for authenticating to Azure Artifacts authenticated feeds.
#>
@ -55,6 +57,8 @@ Param (
[Parameter()]
[switch]$Localization,
[Parameter()]
[switch]$SBOM,
[Parameter()]
[string]$AccessToken
)
@ -111,6 +115,14 @@ try {
$EnvVars['LocLanguages'] = "JPN"
}
if ($SBOM) {
Write-Host "Installing MicroBuild SBOM plugin" -ForegroundColor $HeaderColor
& $InstallNuGetPkgScriptPath MicroBuild.Plugins.Sbom -source $MicroBuildPackageSource -Verbosity $nugetVerbosity
$PkgMicrosoft_ManifestTool_CrossPlatform = & $InstallNuGetPkgScriptPath Microsoft.ManifestTool.CrossPlatform -source 'https://1essharedassets.pkgs.visualstudio.com/1esPkgs/_packaging/SBOMTool/nuget/v3/index.json' -Verbosity $nugetVerbosity
$EnvVars['GenerateSBOM'] = "true"
$EnvVars['PkgMicrosoft_ManifestTool_CrossPlatform'] = $PkgMicrosoft_ManifestTool_CrossPlatform
}
& "$PSScriptRoot/tools/Set-EnvVars.ps1" -Variables $EnvVars -PrependPath $PrependPath | Out-Null
}
catch {

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

@ -2,22 +2,14 @@
<configuration>
<config>
<add key="repositorypath" value="packages" />
<add key="signatureValidationMode" value="require" />
</config>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="msft_consumption" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/msft_consumption/nuget/v3/index.json" />
</packageSources>
<trustedSigners>
<repository name="nuget" serviceIndex="https://api.nuget.org/v3/index.json">
<owners>Microsoft;xunit;manuel.roemer;sharwell;jamesnk;aarnott;MarcoRossignoli;Thecentury;kzu;castleproject</owners>
<certificate fingerprint="0e5f38f57dc1bcc806d8494f4f90fbcedd988b46760709cbeec6f4219aa6157d" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
<certificate fingerprint="5a2901d6ada3d18260b9c6dfe2133c95d74b9eef6ae0e5dc334c8454d1477df4" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
</repository>
<author name="Microsoft">
<certificate fingerprint="aa12da22a49bce7d5c1ae64cc1f3d892f150da76140f210abd2cbffca2c18a27" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
<certificate fingerprint="3f9001ea83c560d712c24cf213c3d312cb3bff51ee89435d3430bd06b5d0eece" hashAlgorithm="SHA256" allowUntrustedRoot="false" />
</author>
</trustedSigners>
<disabledPackageSources>
<!-- Defend against user or machine level disabling of sources that we list in this file. -->
<clear />
</disabledPackageSources>
</configuration>

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

@ -23,7 +23,4 @@
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.1" PrivateAssets="all" />
</ItemGroup>
</Project>

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

@ -10,6 +10,9 @@
},
"fileNamingConvention": "stylecop",
"xmlHeader": false
},
"orderingRules": {
"usingDirectivesPlacement": "outsideNamespace"
}
}
}

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

@ -50,3 +50,6 @@ 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

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

@ -5,8 +5,4 @@
<IsPackable>false</IsPackable>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Internal.MicroBuild.NonShipping" Version="$(MicroBuildVersion)" PrivateAssets="all" />
</ItemGroup>
</Project>

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

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

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

@ -0,0 +1,7 @@
<Project>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Packages.props))\Directory.Packages.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, Directory.Packages.props))' != '' " />
<ItemGroup>
<GlobalPackageReference Include="Microsoft.VisualStudio.Internal.MicroBuild.NonShipping" Version="$(MicroBuildVersion)" />
</ItemGroup>
</Project>

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

@ -1,13 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netcoreapp3.1;net5.0</TargetFrameworks>
<TargetFrameworks>net472;netcoreapp3.1;net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="coverlet.msbuild" Version="3.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Moq" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.VisualStudio.Validation\Microsoft.VisualStudio.Validation.csproj" />

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

@ -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'
@ -72,7 +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)) { mkdir $OutDir }
if (!(Test-Path $OutDir)) { New-Item -ItemType Directory -Path $OutDir | Out-Null }
try {
(New-Object System.Net.WebClient).DownloadFile($Uri, $OutFile)
} finally {
@ -83,40 +91,36 @@ 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
$TypedVersion = [Version]$Version
if ($TypedVersion.Build -eq -1) {
$versionInfo = -Split (Invoke-WebRequest -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sdkOrRuntime/$Version/latest.version" -UseBasicParsing)
$versionInfo = -Split (Invoke-WebRequest -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sku/$Version/latest.version" -UseBasicParsing)
$Version = $versionInfo[-1]
}
$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)
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 ($Runtime) {
if ($release.runtime.version -eq $Version) {
$filesElement = $release.runtime.files
}
} else {
if ($release.sdk.version -eq $Version) {
$filesElement = $release.sdk.files
}
if ($release.$sku.version -eq $Version) {
$filesElement = $release.$sku.files
}
if ($filesElement) {
foreach ($file in $filesElement) {
if ($file.rid -eq "win-$arch") {
if ($file.rid -eq "win-$Architecture") {
$url = $file.url
Break
}
@ -131,26 +135,23 @@ Function Get-InstallerExe($Version, [switch]$Runtime) {
if ($url) {
Get-FileFromWeb -Uri $url -OutDir $DotNetInstallScriptRoot
} else {
Write-Error "Unable to find release of $sdkOrRuntime v$Version"
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';
@ -161,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)
}
}
}
@ -182,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"
@ -219,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 = @()