-
Notifications
You must be signed in to change notification settings - Fork 38
M⚠️ ◾ Automated Package Update #819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5a23446
b7f8e53
c0d9eb7
bfb26c8
88eb82c
671dd97
1c56edc
4b27d31
8c3190a
287fbe0
c56db37
1a02929
1cf02c9
331b09d
07d2d47
0455764
1cbd892
3e92781
fc9b6c7
527230e
34493b9
f2afff8
f5431d8
cd5081d
852325b
0150f4e
6c0ff0c
3d8c054
7d85dac
2e990e3
3188132
d9a33c9
de397b9
483c42f
46a3008
ef098de
c062660
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,359 @@ | ||||||||||||||||||||||||||||||||||||||||||
| <# | ||||||||||||||||||||||||||||||||||||||||||
| .SYNOPSIS | ||||||||||||||||||||||||||||||||||||||||||
| Updates .NET SDK and MSBuild SDK versions in global.json file. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .DESCRIPTION | ||||||||||||||||||||||||||||||||||||||||||
| Updates the .NET SDK version by querying the latest release from aka.ms redirects, | ||||||||||||||||||||||||||||||||||||||||||
| and updates MSBuild SDK package versions using 'dotnet package search'. | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER GlobalJsonPath | ||||||||||||||||||||||||||||||||||||||||||
| Relative path to the global.json file from the source directory. | ||||||||||||||||||||||||||||||||||||||||||
| Default: "global.json" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER SdkChannel | ||||||||||||||||||||||||||||||||||||||||||
| The .NET SDK release channel to track. Options: STS, LTS, 8.0, 9.0, etc. | ||||||||||||||||||||||||||||||||||||||||||
| Default: "STS" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER SourcesDirectory | ||||||||||||||||||||||||||||||||||||||||||
| The root source directory containing the global.json file. | ||||||||||||||||||||||||||||||||||||||||||
| Default: $env:BUILD_SOURCESDIRECTORY (Azure Pipelines variable) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .PARAMETER FailOnError | ||||||||||||||||||||||||||||||||||||||||||
| If $true, throws an exception on SDK lookup failures. If $false, logs warnings and continues. | ||||||||||||||||||||||||||||||||||||||||||
| Default: $false | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .NOTES | ||||||||||||||||||||||||||||||||||||||||||
| Verbose logging is automatically enabled when Azure Pipelines System.Debug is set to 'true'. | ||||||||||||||||||||||||||||||||||||||||||
| To enable verbose logging, set the system.debug variable in your pipeline or run with: | ||||||||||||||||||||||||||||||||||||||||||
| variables: | ||||||||||||||||||||||||||||||||||||||||||
| system.debug: true | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .EXAMPLE | ||||||||||||||||||||||||||||||||||||||||||
| .\Update-DotNetSdkVersions.ps1 | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .EXAMPLE | ||||||||||||||||||||||||||||||||||||||||||
| .\Update-DotNetSdkVersions.ps1 -SdkChannel "LTS" -FailOnError $true | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| .EXAMPLE | ||||||||||||||||||||||||||||||||||||||||||
| $env:SYSTEM_DEBUG = 'true'; .\Update-DotNetSdkVersions.ps1 -GlobalJsonPath "global.json" | ||||||||||||||||||||||||||||||||||||||||||
| #> | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| [CmdletBinding()] | ||||||||||||||||||||||||||||||||||||||||||
| param( | ||||||||||||||||||||||||||||||||||||||||||
| [Parameter(Mandatory = $false)] | ||||||||||||||||||||||||||||||||||||||||||
| [string]$GlobalJsonPath = "global.json", | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| [Parameter(Mandatory = $false)] | ||||||||||||||||||||||||||||||||||||||||||
| [string]$SdkChannel = "STS", | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| [Parameter(Mandatory = $false)] | ||||||||||||||||||||||||||||||||||||||||||
| [string]$SourcesDirectory = $env:BUILD_SOURCESDIRECTORY, | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| [Parameter(Mandatory = $false)] | ||||||||||||||||||||||||||||||||||||||||||
| [bool]$FailOnError = $false | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # Auto-detect verbose logging from Azure Pipelines System.Debug variable | ||||||||||||||||||||||||||||||||||||||||||
| $EnableVerboseLogging = ($env:SYSTEM_DEBUG -eq 'true') -or ($env:SYSTEM_DEBUG -eq '1') | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $ErrorActionPreference = if ($FailOnError) { "Stop" } else { "Continue" } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # Helper function for version comparison | ||||||||||||||||||||||||||||||||||||||||||
| function Get-LatestVersionFromString { | ||||||||||||||||||||||||||||||||||||||||||
| param ( | ||||||||||||||||||||||||||||||||||||||||||
| [string]$First, | ||||||||||||||||||||||||||||||||||||||||||
| [string]$Second | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (-not $First) { return $Second } | ||||||||||||||||||||||||||||||||||||||||||
| if (-not $Second) { return $First } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| function Get-VersionFromString { | ||||||||||||||||||||||||||||||||||||||||||
| param ([string]$Value) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $splitIndex = $Value.IndexOf('-') | ||||||||||||||||||||||||||||||||||||||||||
| if ($splitIndex -eq -1) { | ||||||||||||||||||||||||||||||||||||||||||
| $versionString = $Value | ||||||||||||||||||||||||||||||||||||||||||
| $suffix = '' | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| $versionString = $Value.Substring(0, $splitIndex) | ||||||||||||||||||||||||||||||||||||||||||
| $suffix = $Value.Substring($splitIndex) | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $version = $null | ||||||||||||||||||||||||||||||||||||||||||
| if (-not [System.Version]::TryParse($versionString, [ref]$version)) { | ||||||||||||||||||||||||||||||||||||||||||
| $version = $versionString | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return [PSCustomObject]@{ Version = $version; Suffix = $suffix } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $firstVersionObject = Get-VersionFromString $First | ||||||||||||||||||||||||||||||||||||||||||
| $secondVersionObject = Get-VersionFromString $Second | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if ($firstVersionObject.Version -eq $secondVersionObject.Version) { | ||||||||||||||||||||||||||||||||||||||||||
| if (-not $firstVersionObject.Suffix) { return $First } | ||||||||||||||||||||||||||||||||||||||||||
| if (-not $secondVersionObject.Suffix) { return $Second } | ||||||||||||||||||||||||||||||||||||||||||
| if ($firstVersionObject.Suffix -lt $secondVersionObject.Suffix) { return $Second } | ||||||||||||||||||||||||||||||||||||||||||
| return $First | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if ($firstVersionObject.Version -lt $secondVersionObject.Version) { return $Second } | ||||||||||||||||||||||||||||||||||||||||||
| return $First | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| function Test-PreReleaseVersion { | ||||||||||||||||||||||||||||||||||||||||||
| param ([string]$Version) | ||||||||||||||||||||||||||||||||||||||||||
| return $Version.Contains('-') | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| function Get-LatestSdkVersion { | ||||||||||||||||||||||||||||||||||||||||||
| param ([string]$Channel = "STS") | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $sdkRedirectUrl = "https://aka.ms/dotnet/$Channel/dotnet-sdk-win-x64.zip" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||
| if ($EnableVerboseLogging) { | ||||||||||||||||||||||||||||||||||||||||||
| Write-Host " [VERBOSE] Querying SDK redirect URL: $sdkRedirectUrl" | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # Follow redirects automatically and get final URL | ||||||||||||||||||||||||||||||||||||||||||
| $response = Invoke-WebRequest -Uri $sdkRedirectUrl -Method HEAD -MaximumRedirection 10 -UseBasicParsing | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if ($EnableVerboseLogging) { | ||||||||||||||||||||||||||||||||||||||||||
| Write-Host " [VERBOSE] Response status: $($response.StatusCode)" | ||||||||||||||||||||||||||||||||||||||||||
| Write-Host " [VERBOSE] Response headers: $($response.Headers | ConvertTo-Json -Compress)" | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # PowerShell Core: Get final URL from response object | ||||||||||||||||||||||||||||||||||||||||||
| $finalUrl = $response.BaseResponse.RequestMessage.RequestUri.AbsoluteUri | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (-not $finalUrl) { | ||||||||||||||||||||||||||||||||||||||||||
| throw "Could not determine final redirect URL from response" | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Write-Host "Resolved SDK URL: $finalUrl" | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # URL format: https://dotnetcli.azureedge.net/dotnet/Sdk/<version>/dotnet-sdk-<version>-win-x64.zip | ||||||||||||||||||||||||||||||||||||||||||
| # Pattern: \d+ for major/minor to support multi-digit versions (e.g., 10.0.101) | ||||||||||||||||||||||||||||||||||||||||||
| $version = ($finalUrl | Select-String -Pattern "\d+\.\d+\.\d{3}").Matches.Value | ||||||||||||||||||||||||||||||||||||||||||
| if (-not $version) { | ||||||||||||||||||||||||||||||||||||||||||
| throw "Failed to extract version from URL: $finalUrl" | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| Write-Host "Latest .NET SDK version: $version" | ||||||||||||||||||||||||||||||||||||||||||
| return $version | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| catch { | ||||||||||||||||||||||||||||||||||||||||||
| $errorMsg = "Failed to retrieve SDK version from ${sdkRedirectUrl}: $($_.Exception.Message)" | ||||||||||||||||||||||||||||||||||||||||||
| if ($FailOnError) { | ||||||||||||||||||||||||||||||||||||||||||
| throw $errorMsg | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| Write-Warning $errorMsg | ||||||||||||||||||||||||||||||||||||||||||
| return $null | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| function Get-LatestPackageVersion { | ||||||||||||||||||||||||||||||||||||||||||
| param ( | ||||||||||||||||||||||||||||||||||||||||||
| [string]$PackageId, | ||||||||||||||||||||||||||||||||||||||||||
| [bool]$IncludePrerelease | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||
| $prereleaseFlag = if ($IncludePrerelease) { "--prerelease" } else { "" } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| # Check if NuGet.config exists in the sources directory | ||||||||||||||||||||||||||||||||||||||||||
| $nugetConfigPath = Join-Path $SourcesDirectory "NuGet.config" | ||||||||||||||||||||||||||||||||||||||||||
| $configSourceFlag = "" | ||||||||||||||||||||||||||||||||||||||||||
| if (Test-Path $nugetConfigPath) { | ||||||||||||||||||||||||||||||||||||||||||
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | ||||||||||||||||||||||||||||||||||||||||||
| if ($EnableVerboseLogging) { | ||||||||||||||||||||||||||||||||||||||||||
| Write-Host " [VERBOSE] Using NuGet.config from: $nugetConfigPath" | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
| Write-Warning "NuGet.config not found at: $nugetConfigPath - search may not find private feeds" | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+167
to
+176
|
||||||||||||||||||||||||||||||||||||||||||
| # Check if NuGet.config exists in the sources directory | |
| $nugetConfigPath = Join-Path $SourcesDirectory "NuGet.config" | |
| $configSourceFlag = "" | |
| if (Test-Path $nugetConfigPath) { | |
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | |
| if ($EnableVerboseLogging) { | |
| Write-Host " [VERBOSE] Using NuGet.config from: $nugetConfigPath" | |
| } | |
| } else { | |
| Write-Warning "NuGet.config not found at: $nugetConfigPath - search may not find private feeds" | |
| # Check if NuGet.Config exists in the sources directory | |
| $nugetConfigPath = Join-Path $SourcesDirectory "NuGet.Config" | |
| $configSourceFlag = "" | |
| if (Test-Path $nugetConfigPath) { | |
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | |
| if ($EnableVerboseLogging) { | |
| Write-Host " [VERBOSE] Using NuGet.Config from: $nugetConfigPath" | |
| } | |
| } else { | |
| Write-Warning "NuGet.Config not found at: $nugetConfigPath - search may not find private feeds" |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invoke-Expression executes a constructed command string, which is error-prone for escaping and increases the blast radius of unexpected input. Since $PackageId and paths are interpolated into the string, prefer invoking dotnet with the call operator (&) and explicit arguments instead.
This will be safer and more reliable across different package IDs/paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$SourcesDirectorydefaults to$env:BUILD_SOURCESDIRECTORY, which won’t be set in GitHub Actions and may be empty locally. LaterJoin-Path $SourcesDirectory ...will throw when$SourcesDirectoryis null/empty.Add the same normalization/validation fallback used in
Update-NuGetPackageVersions.ps1(e.g., fall back to$env:GITHUB_WORKSPACEand thenGet-Location).