Skip to content

M⚠️ ◾ Automated Package Update#824

Closed
neilr81 wants to merge 39 commits into
mainfrom
automation/package-update-21805928402
Closed

M⚠️ ◾ Automated Package Update#824
neilr81 wants to merge 39 commits into
mainfrom
automation/package-update-21805928402

Conversation

@neilr81
Copy link
Copy Markdown
Contributor

@neilr81 neilr81 commented Feb 8, 2026

This PR was created automatically by the workflow run 21805928402.

neilr81 and others added 30 commits February 7, 2026 14:08
This script updates NuGet package versions in the Directory.Packages.props file by querying the latest available versions and updating the Version attributes accordingly, while respecting the PreserveMajor attribute and pre-release version detection.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Changed the trigger for package updates to a scheduled cron job.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Initial plan

* Gate PR creation on changes detection flag

Co-authored-by: neilr81 <49037171+neilr81@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: neilr81 <49037171+neilr81@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Removed GitHub CLI installation step from workflow.
Removed the 'powershell' label from the automated package update PR.
This script updates .NET SDK and MSBuild SDK versions in the global.json file by querying the latest releases and modifying the file accordingly.
@neilr81 neilr81 requested a review from a team as a code owner February 8, 2026 21:46
@neilr81 neilr81 added the automation Item has been created automatically. label Feb 8, 2026
Copilot AI review requested due to automatic review settings February 8, 2026 21:46
@neilr81 neilr81 self-assigned this Feb 8, 2026
@neilr81 neilr81 added the automation Item has been created automatically. label Feb 8, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 8, 2026

PR Metrics

Try to keep pull requests smaller than 400 lines of new product code by following the Single Responsibility Principle (SRP).
⚠️ Consider adding additional tests.

Lines
Product Code 709
Test Code -
Subtotal 709
Ignored Code 68
Total 777

Metrics computed by PR Metrics. Add it to your Azure DevOps and GitHub PRs!

@github-actions github-actions Bot changed the title Automated Package Update M⚠️ ◾ Automated Package Update Feb 8, 2026
@neilr81 neilr81 closed this Feb 8, 2026
@neilr81 neilr81 deleted the automation/package-update-21805928402 branch February 8, 2026 21:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Automates dependency maintenance by adding a GitHub Actions workflow and PowerShell scripts to update centrally-managed NuGet package versions (and SDK versions), plus applies an automated package version bump in Directory.Packages.props.

Changes:

  • Bump MSTest package versions in Directory.Packages.props and normalize XML formatting.
  • Add a scheduled GitHub Actions workflow to run package update automation and open a PR.
  • Add PowerShell automation scripts to update NuGet package versions and .NET SDK/MSBuild SDK versions.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
Directory.Packages.props Updates MSTest versions and reformats PackageVersion entries.
.github/workflows/package-update.yml Adds a scheduled automation workflow that runs update script and opens a PR.
.github/scripts/Update-NuGetPackageVersions.ps1 Adds script to search latest package versions and update Directory.Packages.props AutoUpdate groups.
.github/scripts/Update-DotNetSdkVersions.ps1 Adds script to update global.json SDK/MSBuild SDK versions.

Comment on lines +3 to +7
on:
schedule:
- cron: "0 6 * * 1"
pull_request:
branches: [ "main" ]
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow is configured to run on pull_request events and can create/push a new branch + open a PR. This is likely to spam PRs and can recurse when the automation PR itself triggers the workflow. Limit this workflow to schedule (and optionally workflow_dispatch) rather than pull_request.

Copilot uses AI. Check for mistakes.
Comment on lines +147 to +150
# Prefer NuGet-GitHub.Config (used on GitHub runners) when present, otherwise fall back to NuGet.config
$nugetGithubConfigPath = Join-Path $SourcesDirectory "NuGet-GitHub.Config"
$nugetConfigPath = Join-Path $SourcesDirectory "NuGet.config"
$configSourceFlag = ""
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repo root uses NuGet.Config (capital C), but the script looks for NuGet.config. On case-sensitive filesystems this will never be found, so the intended feeds/config won’t be used. Update this to match the repo’s filename (or check both casings).

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +129
$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
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invoke-WebRequest result handling is not compatible across Windows PowerShell 5.1 vs PowerShell Core: -UseBasicParsing is legacy, and $response.BaseResponse.RequestMessage.RequestUri is not available on WinPS 5.1. If this script is intended for Azure Pipelines (often WinPS 5.1), use a response URI property that exists there (e.g., BaseResponse.ResponseUri) and avoid -UseBasicParsing.

Suggested change
$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
$response = Invoke-WebRequest -Uri $sdkRedirectUrl -Method HEAD -MaximumRedirection 10
if ($EnableVerboseLogging) {
Write-Host " [VERBOSE] Response status: $($response.StatusCode)"
Write-Host " [VERBOSE] Response headers: $($response.Headers | ConvertTo-Json -Compress)"
}
# Get final URL from response object (compatible with Windows PowerShell 5.1 and PowerShell Core)
$finalUrl = $response.BaseResponse.ResponseUri.AbsoluteUri

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +125
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
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get-LatestVersionFromString compares pre-release suffixes lexicographically (string compare). This gives incorrect ordering for versions like -preview.10 vs -preview.2, which can cause the script to select the wrong "latest" version. Consider using a SemVer/NuGetVersion-aware comparison (or parsing numeric components of the suffix) instead of plain string comparison.

Copilot uses AI. Check for mistakes.
Comment on lines +94 to +99
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
}
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get-LatestVersionFromString compares pre-release suffixes lexicographically (string compare), which can order -preview.10 before -preview.2. This can select the wrong latest SDK/MSBuild SDK version when pre-releases are involved. Use a SemVer/NuGetVersion-aware comparison (or parse numeric suffix parts) instead.

Copilot uses AI. Check for mistakes.
[Parameter(Mandatory = $false)]
[bool]$FailOnError = $false
)

Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$SourcesDirectory defaults to $env:BUILD_SOURCESDIRECTORY but the script doesn’t normalize/validate it like the package update script does. If the env var is unset/empty, Join-Path will fail. Add the same fallback logic (e.g., $env:GITHUB_WORKSPACE then Get-Location) and validate the directory exists.

Suggested change
# Normalize and validate the sources directory to avoid Join-Path failures
if ([string]::IsNullOrWhiteSpace($SourcesDirectory)) {
if (-not [string]::IsNullOrWhiteSpace($env:BUILD_SOURCESDIRECTORY)) {
$SourcesDirectory = $env:BUILD_SOURCESDIRECTORY
} elseif (-not [string]::IsNullOrWhiteSpace($env:GITHUB_WORKSPACE)) {
$SourcesDirectory = $env:GITHUB_WORKSPACE
} else {
$SourcesDirectory = (Get-Location).Path
}
}
try {
# Resolve to a full, normalized path and ensure it exists as a directory
$resolvedSourcesDirectory = Resolve-Path -Path $SourcesDirectory -ErrorAction Stop
if (-not (Test-Path -Path $resolvedSourcesDirectory -PathType Container)) {
throw "Sources directory '$SourcesDirectory' is not a valid directory."
}
$SourcesDirectory = $resolvedSourcesDirectory.ProviderPath
}
catch {
$message = "Failed to resolve sources directory from '$SourcesDirectory'."
if ($FailOnError) {
throw "$message Error: $($_.Exception.Message)"
} else {
Write-Warning "$message Falling back to current location."
$fallback = (Get-Location).Path
$SourcesDirectory = $fallback
}
}

Copilot uses AI. Check for mistakes.
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"
Copy link

Copilot AI Feb 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repo root uses NuGet.Config (capital C), but this script looks for NuGet.config. On case-sensitive filesystems the config won’t be found, so package searches may miss required feeds. Update the filename (or check both casings).

Suggested change
# 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 / NuGet.Config exists in the sources directory
$nugetConfigLower = Join-Path $SourcesDirectory "NuGet.config"
$nugetConfigUpper = Join-Path $SourcesDirectory "NuGet.Config"
$configSourceFlag = ""
$nugetConfigPath = $null
if (Test-Path $nugetConfigLower) {
$nugetConfigPath = $nugetConfigLower
} elseif (Test-Path $nugetConfigUpper) {
$nugetConfigPath = $nugetConfigUpper
}
if ($nugetConfigPath) {
$configSourceFlag = "--configfile `"$nugetConfigPath`""
if ($EnableVerboseLogging) {
Write-Host " [VERBOSE] Using NuGet config from: $nugetConfigPath"
}
} else {
Write-Warning "NuGet config file not found (checked: $nugetConfigLower, $nugetConfigUpper) - search may not find private feeds"

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation Item has been created automatically.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants