diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 79ad7dda2..e2f24dc2f 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "powershell": { - "version": "7.5.2", + "version": "7.5.3", "commands": [ "pwsh" ], diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f06bc4ca2..5526144c2 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:9.0.301-noble@sha256:4fd7d3e5aeb6cfb75e923a54cdb0b6e858b27ad3b517837917c57c2e632b5694 +FROM mcr.microsoft.com/dotnet/sdk:9.0.305-noble@sha256:802e64ab9e113bdfa5d476ae00c7b40ab5c42da1792731c41a47f43bc4e74bdb # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..085935029 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,23 @@ +# Copilot instructions for this repository + +## High level guidance + +* Review the `CONTRIBUTING.md` file for instructions to build and test the software. +* Set the `NBGV_GitEngine` environment variable to `Disabled` before running any `dotnet` or `msbuild` commands. + +## Software Design + +* Design APIs to be highly testable, and all functionality should be tested. +* Avoid introducing binary breaking changes in public APIs of projects under `src` unless their project files have `IsPackable` set to `false`. + +## Testing + +* There should generally be one test project (under the `test` directory) per shipping project (under the `src` directory). Test projects are named after the project being tested with a `.Test` suffix. +* Tests should use the Xunit testing framework. +* Some tests are known to be unstable. When running tests, you should skip the unstable ones by running `dotnet test --filter "TestCategory!=FailsInCloudTest"`. + +## Coding style + +* Honor StyleCop rules and fix any reported build warnings *after* getting tests to pass. +* In C# files, use namespace *statements* instead of namespace *blocks* for all new files. +* Add API doc comments to all new public and internal members. diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index 053f56e95..eb69d92e8 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -26,7 +26,7 @@ jobs: # You can define any steps you want, and they will run before the agent starts. # If you do not check out your code, Copilot will do this for you. steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: ⚙ Install prerequisites diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0a8f8215d..a7155c4cf 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -5,13 +5,6 @@ on: branches: - main -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - actions: read - pages: write - id-token: write - contents: read - # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. concurrency: @@ -20,12 +13,18 @@ concurrency: jobs: publish-docs: + # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages + permissions: + actions: read + pages: write + id-token: write + contents: read environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: ⚙ Install prerequisites @@ -35,7 +34,7 @@ jobs: name: 📚 Generate documentation - name: Upload artifact - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 + uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4 with: path: docfx/_site diff --git a/.github/workflows/docs_validate.yml b/.github/workflows/docs_validate.yml index dd7b19121..50a35d770 100644 --- a/.github/workflows/docs_validate.yml +++ b/.github/workflows/docs_validate.yml @@ -13,11 +13,11 @@ jobs: name: 📚 Doc validation runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - name: 🔗 Markup Link Checker (mlc) - uses: becheran/mlc@88c9db09b8dabab813a2edd13f955b36aa73657a # v0.22.0 + uses: becheran/mlc@18a06b3aa2901ca197de59c8b0b1f54fdba6b3fa # v1.0.0 with: args: --do-not-warn-for-redirect-to https://learn.microsoft.com*,https://dotnet.microsoft.com/*,https://dev.azure.com/*,https://app.codecov.io/*,https://badges.gitter.im/*,https://github.com/*,https://app.gitter.im/* -p docfx -i https://aka.ms/onboardsupport,https://aka.ms/spot,https://msrc.microsoft.com/*,https://www.microsoft.com/msrc*,https://microsoft.com/msrc*,https://microsoft.sharepoint.com/* - name: ⚙ Install prerequisites diff --git a/.github/workflows/libtemplate-update.yml b/.github/workflows/libtemplate-update.yml index 7d0a67a0b..f5cf8666f 100644 --- a/.github/workflows/libtemplate-update.yml +++ b/.github/workflows/libtemplate-update.yml @@ -17,7 +17,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. diff --git a/.gitignore b/.gitignore index cc2b12470..1b7799301 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore # User-specific files *.rsuser diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bfbaf9c8f..d851fba98 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,7 +44,7 @@ assuming the working directory is the root of this repository: msbuild src ``` -[pwsh]: https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-6 +[pwsh]: https://learn.microsoft.com/powershell/scripting/install/installing-powershell ## Releases @@ -58,9 +58,9 @@ Push the tag. When your repo is hosted by GitHub and you are using GitHub Actions, you should create a GitHub Release using the standard GitHub UI. Having previously used `nbgv tag` and pushing the tag will help you identify the precise commit and name to use for this release. -After publishing the release, the `.github\workflows\release.yml` workflow will be automatically triggered, which will: +After publishing the release, the `.github/workflows/release.yml` workflow will be automatically triggered, which will: -1. Find the most recent `.github\workflows\build.yml` GitHub workflow run of the tagged release. +1. Find the most recent `.github/workflows/build.yml` GitHub workflow run of the tagged release. 1. Upload the `deployables` artifact from that workflow run to your GitHub Release. 1. If you have `NUGET_API_KEY` defined as a secret variable for your repo or org, any nuget packages in the `deployables` artifact will be pushed to nuget.org. @@ -71,7 +71,7 @@ Trigger the pipeline by adding the `auto-release` tag on a run of your main `azu ## Tutorial and API documentation -API and hand-written docs are found under the `docfx/` directory. and are built by [docfx](https://dotnet.github.io/docfx/). +API and hand-written docs are found under the `docfx/` directory and are built by [docfx](https://dotnet.github.io/docfx/). You can make changes and host the site locally to preview them by switching to that directory and running the `dotnet docfx --serve` command. After making a change, you can rebuild the docs site while the localhost server is running by running `dotnet docfx` again from a separate terminal. @@ -93,11 +93,11 @@ If Renovate is not creating pull requests when you expect it to, check that the ### Maintaining your repo based on this template The best way to keep your repo in sync with Library.Template's evolving features and best practices is to periodically merge the template into your repo: -` + ```ps1 git fetch git checkout origin/main -.\tools\MergeFrom-Template.ps1 +./tools/MergeFrom-Template.ps1 # resolve any conflicts, then commit the merge commit. git push origin -u HEAD ``` diff --git a/CodeQL.yml b/CodeQL.yml new file mode 100644 index 000000000..903500b55 --- /dev/null +++ b/CodeQL.yml @@ -0,0 +1,3 @@ +path_classifiers: + library: + - 'test/**' diff --git a/Directory.Build.props b/Directory.Build.props index 37ac88278..b0b65b693 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,6 +7,7 @@ $(RepoRootPath)bin\$(MSBuildProjectName)\ $(RepoRootPath)bin\Packages\$(Configuration)\NuGet\ $(RepoRootPath)bin\Packages\$(Configuration)\Vsix\$(Platform)\ + $(RepoRootPath)bin\Packages\$(Configuration)\Vsix\ $(VSIXOutputPath) enable disable @@ -15,6 +16,9 @@ true true + + true + true diff --git a/Directory.Packages.props b/Directory.Packages.props index 81362d7d4..bca56cae8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,7 +4,7 @@ true true - 2.0.198 + 2.0.201 3.11.0 4.13.0 1.1.2 @@ -51,7 +51,7 @@ - + diff --git a/SECURITY.md b/SECURITY.md index 0dc4b6a77..29306956d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,7 +4,7 @@ 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. +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://learn.microsoft.com/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. ## Reporting Security Issues diff --git a/azure-pipelines/Install-NuGetPackage.ps1 b/azure-pipelines/Install-NuGetPackage.ps1 deleted file mode 100644 index f1db577ab..000000000 --- a/azure-pipelines/Install-NuGetPackage.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -<# -.SYNOPSIS - Installs a NuGet package. -.PARAMETER PackageID - The Package ID to install. -.PARAMETER Version - The version of the package to install. If unspecified, the latest stable release is installed. -.PARAMETER Source - The package source feed to find the package to install from. -.PARAMETER PackagesDir - 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( - [Parameter(Position=1,Mandatory=$true)] - [string]$PackageId, - [Parameter()] - [string]$Version, - [Parameter()] - [string]$Source, - [Parameter()] - [switch]$Prerelease, - [Parameter()] - [string]$PackagesDir="$PSScriptRoot\..\packages", - [Parameter()] - [string]$ConfigFile="$PSScriptRoot\..\nuget.config", - [Parameter()] - [ValidateSet('Quiet','Normal','Detailed')] - [string]$Verbosity='normal' -) - -$nugetPath = & "$PSScriptRoot\..\tools\Get-NuGetTool.ps1" - -try { - Write-Verbose "Installing $PackageId..." - $nugetArgs = "Install",$PackageId,"-OutputDirectory",$PackagesDir,'-ConfigFile',$ConfigFile - if ($Version) { $nugetArgs += "-Version",$Version } - if ($Source) { $nugetArgs += "-FallbackSource",$Source } - if ($Prerelease) { $nugetArgs += "-Prerelease" } - $nugetArgs += '-Verbosity',$Verbosity - - if ($PSCmdlet.ShouldProcess($PackageId, 'nuget install')) { - $p = Start-Process $nugetPath $nugetArgs -NoNewWindow -Wait -PassThru - if ($null -ne $p.ExitCode -and $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 -} diff --git a/azure-pipelines/PostPRMessage.ps1 b/azure-pipelines/PostPRMessage.ps1 index 4a2b7886e..4075f3921 100644 --- a/azure-pipelines/PostPRMessage.ps1 +++ b/azure-pipelines/PostPRMessage.ps1 @@ -8,7 +8,7 @@ param( $CommentState='Active' ) -# See https://docs.microsoft.com/en-us/dotnet/api/microsoft.teamfoundation.sourcecontrol.webapi.commentthreadstatus?view=azure-devops-dotnet +# See https://learn.microsoft.com/dotnet/api/microsoft.teamfoundation.sourcecontrol.webapi.commentthreadstatus if ($CommentState -eq 'Active') { $StatusCode = 1 } elseif ($CommentState -eq 'ByDesign') { @@ -38,7 +38,7 @@ $body = ConvertTo-Json @{ 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 +# https://learn.microsoft.com/rest/api/azure/devops/git/pull-request-threads $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 { diff --git a/azure-pipelines/apiscan.yml b/azure-pipelines/apiscan.yml index c3c8aed16..a1d07e104 100644 --- a/azure-pipelines/apiscan.yml +++ b/azure-pipelines/apiscan.yml @@ -49,8 +49,10 @@ jobs: isLargeApp: false toolVersion: Latest preserveLogsFolder: true + azureSubscription: VSEng-APIScanSC env: - AzureServicesAuthConnectionString: runAs=App;AppId=$(ApiScanClientId) + AzureServicesAuthConnectionString: $(APIScanAuthConnectionString) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) # File bugs when APIScan finds issues - task: TSAUpload@2 diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index 7da084a56..bc7cf3afd 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -123,6 +123,7 @@ jobs: signType: test sbom: enabled: true + sbomToolVersion: 5.0.3 localization: enabled: ${{ parameters.EnableLocalization }} ${{ if eq(variables['Build.Reason'], 'pullRequest') }}: @@ -245,6 +246,7 @@ jobs: parameters: Is1ESPT: ${{ parameters.Is1ESPT }} RunTests: ${{ parameters.RunTests }} + BuildRequiresAccessToken: ${{ parameters.RealSign }} # Real signing on non-Windows machines requires passing through access token to build steps that sign osRID: linux - ${{ if parameters.EnableDotNetFormatCheck }}: - script: dotnet format --verify-no-changes @@ -281,6 +283,7 @@ jobs: parameters: Is1ESPT: ${{ parameters.Is1ESPT }} RunTests: ${{ parameters.RunTests }} + BuildRequiresAccessToken: ${{ parameters.RealSign }} # Real signing on non-Windows machines requires passing through access token to build steps that sign osRID: osx - job: WrapUp diff --git a/azure-pipelines/dotnet.yml b/azure-pipelines/dotnet.yml index f9ca66e10..a6eb4e15e 100644 --- a/azure-pipelines/dotnet.yml +++ b/azure-pipelines/dotnet.yml @@ -5,6 +5,9 @@ parameters: default: false - name: Is1ESPT type: boolean +- name: BuildRequiresAccessToken + type: boolean + default: false - name: osRID type: string @@ -12,6 +15,9 @@ steps: - script: dotnet build tools/dirs.proj -t:build,pack,publish --no-restore -c $(BuildConfiguration) -warnAsError -warnNotAsError:NU1901,NU1902,NU1903,NU1904,LOCTASK002 /bl:"$(Build.ArtifactStagingDirectory)/build_logs/build.binlog" displayName: 🛠 dotnet build + ${{ if parameters.BuildRequiresAccessToken }}: + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - ${{ if not(parameters.IsOptProf) }}: - powershell: tools/dotnet-test-cloud.ps1 -Configuration $(BuildConfiguration) -Agent $(Agent.JobName) -PublishResults diff --git a/azure-pipelines/libtemplate-update.yml b/azure-pipelines/libtemplate-update.yml index 3d7fb7e3b..384be7cfc 100644 --- a/azure-pipelines/libtemplate-update.yml +++ b/azure-pipelines/libtemplate-update.yml @@ -35,6 +35,8 @@ extends: name: AzurePipelines-EO demands: - ImageOverride -equals 1ESPT-Windows2022 + credscan: + enabled: false stages: - stage: Merge diff --git a/azure-pipelines/microbuild.before.yml b/azure-pipelines/microbuild.before.yml index 250715369..d09310b1e 100644 --- a/azure-pipelines/microbuild.before.yml +++ b/azure-pipelines/microbuild.before.yml @@ -17,9 +17,9 @@ parameters: steps: - ${{ if and(not(parameters.IsOptProf), ne(variables['Build.Reason'], 'PullRequest')) }}: # notice@0 requires CG detection to run first, and non-default branches don't inject it automatically. - - ${{ if ne(variables['Build.SourceBranch'], 'refs/heads/main') }}: - - task: ComponentGovernanceComponentDetection@0 - displayName: 🔍 Component Detection + # default branch injection (main) is happening too late for notice@0 to run successfully. Adding this as a workaround. + - task: ComponentGovernanceComponentDetection@0 + displayName: 🔍 Component Detection - task: notice@0 displayName: 🛠️ Generate NOTICE file diff --git a/azure-pipelines/prepare-insertion-stages.yml b/azure-pipelines/prepare-insertion-stages.yml index 0bde9528b..61a79661a 100644 --- a/azure-pipelines/prepare-insertion-stages.yml +++ b/azure-pipelines/prepare-insertion-stages.yml @@ -30,12 +30,15 @@ stages: - download: current artifact: symbols-legacy displayName: 🔻 Download symbols-legacy artifact - - task: MicroBuildArchiveSymbols@5 + - task: MicroBuildArchiveSymbols@6 displayName: 🔣 Archive symbols to Symweb inputs: SymbolsFeatureName: $(SymbolsFeatureName) SymbolsProject: VS SymbolsAgentPath: $(Pipeline.Workspace)/symbols-legacy + azureSubscription: Vseng-SymbolsUpload + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - ${{ if parameters.PackagePush }}: - job: push diff --git a/azure-pipelines/unofficial.yml b/azure-pipelines/unofficial.yml index 0f8147a8c..3f40e0b54 100644 --- a/azure-pipelines/unofficial.yml +++ b/azure-pipelines/unofficial.yml @@ -58,6 +58,8 @@ extends: parameters: sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + credscan: + enabled: false suppression: suppressionFile: $(System.DefaultWorkingDirectory)\azure-pipelines\falsepositives.gdnsuppress enableProductionSDL: ${{ parameters.EnableProductionSDL }} diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml index 3a40395e7..b9d46b7c7 100644 --- a/azure-pipelines/vs-validation.yml +++ b/azure-pipelines/vs-validation.yml @@ -28,6 +28,8 @@ extends: parameters: sdl: sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES + credscan: + enabled: false stages: - stage: Build diff --git a/azurepipelines-coverage.yml b/azurepipelines-coverage.yml index 0cd5dad36..e2dd1f503 100644 --- a/azurepipelines-coverage.yml +++ b/azurepipelines-coverage.yml @@ -1,4 +1,4 @@ -# https://learn.microsoft.com/azure/devops/pipelines/test/codecoverage-for-pullrequests?view=azure-devops +# https://learn.microsoft.com/azure/devops/pipelines/test/codecoverage-for-pullrequests coverage: status: comments: on # add comment to PRs reporting diff in coverage of modified files diff --git a/global.json b/global.json index 5fce40099..b9966e9ed 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.301", + "version": "9.0.305", "rollForward": "patch", "allowPrerelease": false }, diff --git a/init.ps1 b/init.ps1 index 4186329fd..183a7156d 100755 --- a/init.ps1 +++ b/init.ps1 @@ -122,7 +122,7 @@ try { } } - $InstallNuGetPkgScriptPath = "$PSScriptRoot\azure-pipelines\Install-NuGetPackage.ps1" + $InstallNuGetPkgScriptPath = "$PSScriptRoot\tools\Install-NuGetPackage.ps1" $nugetVerbosity = 'quiet' if ($Verbose) { $nugetVerbosity = 'normal' } $MicroBuildPackageSource = 'https://pkgs.dev.azure.com/devdiv/_packaging/MicroBuildToolset%40Local/nuget/v3/index.json' diff --git a/tools/Convert-PDB.ps1 b/tools/Convert-PDB.ps1 index f119a164e..7e1303a2a 100644 --- a/tools/Convert-PDB.ps1 +++ b/tools/Convert-PDB.ps1 @@ -30,7 +30,13 @@ 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 + # This package originally comes from the https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json feed. + # Add this feed as an upstream to whatever feed is in nuget.config if this step fails. + & (& $PSScriptRoot/Get-NuGetTool.ps1) install Microsoft.DiaSymReader.Pdb2Pdb -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir | Out-Null + if ($LASTEXITCODE -ne 0) { + Write-Error "Failed to install Microsoft.DiaSymReader.Pdb2Pdb. Consider adding https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json as an upstream to your nuget.config feed." + return + } } $args = $DllPath,'/out',$OutputPath,'/nowarn','0021' diff --git a/tools/Get-NuGetTool.ps1 b/tools/Get-NuGetTool.ps1 index 8a3b9eeda..bed0cba1d 100644 --- a/tools/Get-NuGetTool.ps1 +++ b/tools/Get-NuGetTool.ps1 @@ -6,7 +6,7 @@ #> Param( [Parameter()] - [string]$NuGetVersion='6.12.2' + [string]$NuGetVersion='6.14.0' ) $toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1" diff --git a/tools/Get-ProcDump.ps1 b/tools/Get-ProcDump.ps1 index 1493fe4b2..6fba954d8 100644 --- a/tools/Get-ProcDump.ps1 +++ b/tools/Get-ProcDump.ps1 @@ -8,7 +8,7 @@ $procDumpToolPath = "$baseDir\procdump.$version\bin" if (-not (Test-Path $procDumpToolPath)) { if (-not (Test-Path $baseDir)) { New-Item -Type Directory -Path $baseDir | Out-Null } $baseDir = (Resolve-Path $baseDir).Path # Normalize it - & (& $PSScriptRoot\Get-NuGetTool.ps1) install procdump -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir -Source https://api.nuget.org/v3/index.json | Out-Null + & (& $PSScriptRoot\Get-NuGetTool.ps1) install procdump -version $version -PackageSaveMode nuspec -OutputDirectory $baseDir | Out-Null } (Resolve-Path $procDumpToolPath).Path diff --git a/tools/Install-NuGetPackage.ps1 b/tools/Install-NuGetPackage.ps1 new file mode 100644 index 000000000..3c11b0f6b --- /dev/null +++ b/tools/Install-NuGetPackage.ps1 @@ -0,0 +1,63 @@ +<# +.SYNOPSIS + Installs a NuGet package. +.PARAMETER PackageID + The Package ID to install. +.PARAMETER Version + The version of the package to install. If unspecified, the latest stable release is installed. +.PARAMETER Source + The package source feed to find the package to install from. +.PARAMETER Prerelease + Include prerelease packages when searching for the latest version. +.PARAMETER ExcludeVersion + Installs the package without adding the version to the folder name. +.PARAMETER DirectDownload + Bypass the local cache when downloading packages. +.PARAMETER PackagesDir + 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( + [Parameter(Position=1,Mandatory=$true)] + [string]$PackageId, + [Parameter()] + [string]$Version, + [Parameter()] + [string]$Source, + [Parameter()] + [switch]$Prerelease, + [Parameter()] + [switch]$ExcludeVersion, + [Parameter()] + [switch]$DirectDownload, + [Parameter()] + [string]$PackagesDir="$PSScriptRoot\..\packages", + [Parameter()] + [string]$ConfigFile="$PSScriptRoot\..\nuget.config", + [Parameter()] + [ValidateSet('Quiet','Normal','Detailed')] + [string]$Verbosity='normal' +) + +$nugetPath = & "$PSScriptRoot\Get-NuGetTool.ps1" + +Write-Verbose "Installing $PackageId..." +$nugetArgs = "Install",$PackageId,"-OutputDirectory",$PackagesDir,'-ConfigFile',$ConfigFile +if ($Version) { $nugetArgs += "-Version",$Version } +if ($Source) { $nugetArgs += "-FallbackSource",$Source } +if ($Prerelease) { $nugetArgs += "-Prerelease" } +if ($ExcludeVersion) { $nugetArgs += '-ExcludeVersion' } +if ($DirectDownload) { $nugetArgs += '-DirectDownload' } +$nugetArgs += '-Verbosity',$Verbosity + +if ($PSCmdlet.ShouldProcess($PackageId, 'nuget install')) { + $p = Start-Process $nugetPath $nugetArgs -NoNewWindow -Wait -PassThru + if ($null -ne $p.ExitCode -and $p.ExitCode -ne 0) { throw } +} + +# Provide the path to the installed package directory to our caller. +Write-Output (Get-ChildItem "$PackagesDir\$PackageId.*")[0].FullName diff --git a/tools/artifacts/VSInsertion.ps1 b/tools/artifacts/VSInsertion.ps1 index ffc7e29ad..a5b940b5d 100644 --- a/tools/artifacts/VSInsertion.ps1 +++ b/tools/artifacts/VSInsertion.ps1 @@ -20,8 +20,8 @@ $PackagesRoot = "$RepoRoot/bin/Packages/$BuildConfiguration" $NuGetPackages = "$PackagesRoot/NuGet" $VsixPackages = "$PackagesRoot/Vsix" -if (!(Test-Path $NuGetPackages)) { - Write-Warning "Skipping because NuGet packages haven't been built yet." +if (!(Test-Path $NuGetPackages) -and !(Test-Path $VsixPackages)) { + Write-Warning "Skipping because NuGet and VSIX packages haven't been built yet." return @{} }