-
Notifications
You must be signed in to change notification settings - Fork 39
M⚠️ ◾ Add GitHub Actions workflow for package updates #794
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
base: main
Are you sure you want to change the base?
Conversation
PR Metrics❌ Try to keep pull requests smaller than 400 lines of new product code by following the Single Responsibility Principle (SRP).
Metrics computed by PR Metrics. Add it to your Azure DevOps and GitHub PRs! |
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.
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.
Pull request overview
Adds a new GitHub Actions workflow intended to run a PowerShell-based update script and automatically open a PR with the resulting changes.
Changes:
- Introduces
.github/workflows/package-update.ymlwith aworkflow_dispatch+pushtrigger. - Runs a PowerShell script, commits any changes to a new branch, pushes it, and opens a PR via
gh.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Changed the trigger for package updates to a scheduled cron job.
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.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
.github/workflows/package-update.yml
Outdated
| git checkout -b $branch | ||
| git add -A | ||
|
|
||
| if (git diff --cached --quiet) { | ||
| echo "No changes detected; exiting." | ||
| exit 0 | ||
| } | ||
|
|
||
| git commit -m "chore(automation): apply PowerShell updates" | ||
| git push --set-upstream origin $branch | ||
|
|
||
| - name: Open PR with gh | ||
| if: success() | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} |
Copilot
AI
Feb 7, 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.
Branch names are based only on github.run_id. Re-runs of the same workflow and/or concurrent runs can collide with an existing branch name and cause the push/PR creation to fail. Include github.run_attempt (and/or add a concurrency group) to ensure uniqueness and avoid duplicate PRs.
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.
@copilot open a new pull request to apply changes based on this feedback
| $updateCount = 0 | ||
|
|
||
| # Find all ItemGroups with AutoUpdate label | ||
| $autoUpdateGroups = $xml.Project.ItemGroup | Where-Object { | ||
| $null -ne $_.Label -and $_.Label -match 'AutoUpdate' | ||
| } | ||
|
|
||
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | ||
|
|
||
| foreach ($itemGroup in $autoUpdateGroups) { | ||
| $packageVersions = $itemGroup.PackageVersion | ||
|
|
||
| if (-not $packageVersions) { continue } |
Copilot
AI
Feb 7, 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.
Directory.Packages.props uses a default XML namespace (xmlns="http://schemas.microsoft.com/developer/msbuild/2003"), so $xml.Project.ItemGroup won’t reliably return ItemGroups. Use SelectNodes/SelectSingleNode with an XmlNamespaceManager (or a local-name() XPath) to find ItemGroup and PackageVersion elements; otherwise the script may report 0 AutoUpdate groups and do nothing.
| $updateCount = 0 | |
| # Find all ItemGroups with AutoUpdate label | |
| $autoUpdateGroups = $xml.Project.ItemGroup | Where-Object { | |
| $null -ne $_.Label -and $_.Label -match 'AutoUpdate' | |
| } | |
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | |
| foreach ($itemGroup in $autoUpdateGroups) { | |
| $packageVersions = $itemGroup.PackageVersion | |
| if (-not $packageVersions) { continue } | |
| # Prepare XML namespace manager for MSBuild default namespace | |
| $namespaceManager = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) | |
| $namespaceManager.AddNamespace('msb', $xml.DocumentElement.NamespaceURI) | |
| $updateCount = 0 | |
| # Find all ItemGroups with AutoUpdate label (namespace-aware) | |
| $autoUpdateGroups = $xml.SelectNodes("/msb:Project/msb:ItemGroup[@Label and contains(@Label, 'AutoUpdate')]", $namespaceManager) | |
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | |
| foreach ($itemGroup in $autoUpdateGroups) { | |
| $packageVersions = $itemGroup.SelectNodes("msb:PackageVersion", $namespaceManager) | |
| if (-not $packageVersions -or $packageVersions.Count -eq 0) { continue } |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
.github/workflows/package-update.yml
Outdated
| - name: Install GitHub CLI | ||
| uses: cli/cli-action@v2 | ||
| with: | ||
| version: 'latest' | ||
|
|
||
| - name: Run PowerShell script | ||
| shell: pwsh | ||
| run: | | ||
| ./.github/scripts/Update-NuGetPackageVersions.ps1 -Verbose | ||
|
|
Copilot
AI
Feb 7, 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.
This workflow runs dotnet package search via the PowerShell script but does not install/pin a .NET SDK. To make runs deterministic and aligned with global.json, add an actions/setup-dotnet step (e.g., using global-json-file) before invoking the script.
* 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>
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.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.
.github/workflows/package-update.yml
Outdated
| - name: Install GitHub CLI | ||
| uses: cli/cli-action@v2 | ||
| with: | ||
| version: 'latest' | ||
|
|
||
| - name: Run PowerShell script | ||
| shell: pwsh | ||
| run: | | ||
| ./.github/scripts/Update-NuGetPackageVersions.ps1 -Verbose | ||
|
|
Copilot
AI
Feb 7, 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.
This workflow invokes dotnet (via the update script) but never installs the repo’s pinned .NET SDK. The repo uses global.json / other workflows install .NET 10 explicitly; without actions/setup-dotnet, this job can start failing when the runner image changes or if dotnet package search isn’t available. Add a setup-dotnet step aligned with the repo’s build workflow.
| # 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: $SourcesDirectory - search may not find private feeds" | ||
| } |
Copilot
AI
Feb 7, 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.
The script looks for NuGet.config and then passes it to dotnet package search --configfile. In this repo the files are NuGet.Config (internal Office feed) and NuGet-GitHub.Config (nuget.org). For GitHub Actions, using NuGet.Config is likely to fail due to missing auth to the internal feed; prefer NuGet-GitHub.Config when running on GitHub Actions (and use the correct filename/casing so it also works on non-Windows runners).
| $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 } |
Copilot
AI
Feb 7, 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.
Prerelease comparison uses a plain string comparison on the suffix (e.g., -rc.10 vs -rc.2), which doesn’t follow NuGet/SemVer precedence rules and can select the wrong “latest” prerelease. Consider using NuGet’s version parsing/ordering (e.g., NuGet.Versioning’s NuGetVersion) or implement proper SemVer prerelease token comparison.
| $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 } | |
| function Compare-PreReleaseSuffix { | |
| param ( | |
| [string]$FirstSuffix, | |
| [string]$SecondSuffix | |
| ) | |
| if ($FirstSuffix -eq $SecondSuffix) { return 0 } | |
| # Trim leading '-' if present | |
| if ($FirstSuffix.StartsWith('-')) { $FirstSuffix = $FirstSuffix.Substring(1) } | |
| if ($SecondSuffix.StartsWith('-')) { $SecondSuffix = $SecondSuffix.Substring(1) } | |
| $firstIdentifiers = $FirstSuffix -split '\.' | |
| $secondIdentifiers = $SecondSuffix -split '\.' | |
| $maxLength = [Math]::Max($firstIdentifiers.Length, $secondIdentifiers.Length) | |
| for ($i = 0; $i -lt $maxLength; $i++) { | |
| if ($i -ge $firstIdentifiers.Length) { return -1 } # fewer identifiers => lower precedence | |
| if ($i -ge $secondIdentifiers.Length) { return 1 } # more identifiers => higher precedence | |
| $firstId = $firstIdentifiers[$i] | |
| $secondId = $secondIdentifiers[$i] | |
| if ($firstId -eq $secondId) { continue } | |
| $firstNum = 0 | |
| $secondNum = 0 | |
| $firstIsNumeric = [int]::TryParse($firstId, [ref]$firstNum) | |
| $secondIsNumeric = [int]::TryParse($secondId, [ref]$secondNum) | |
| if ($firstIsNumeric -and $secondIsNumeric) { | |
| if ($firstNum -lt $secondNum) { return -1 } | |
| if ($firstNum -gt $secondNum) { return 1 } | |
| continue | |
| } | |
| if ($firstIsNumeric -and -not $secondIsNumeric) { return -1 } # numeric < non-numeric | |
| if (-not $firstIsNumeric -and $secondIsNumeric) { return 1 } # non-numeric > numeric | |
| $stringCompare = [string]::CompareOrdinal($firstId, $secondId) | |
| if ($stringCompare -lt 0) { return -1 } | |
| if ($stringCompare -gt 0) { return 1 } | |
| } | |
| return 0 | |
| } | |
| $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 } | |
| $suffixComparison = Compare-PreReleaseSuffix -FirstSuffix $firstVersionObject.Suffix -SecondSuffix $secondVersionObject.Suffix | |
| if ($suffixComparison -lt 0) { return $Second } |
| $updateCount = 0 | ||
|
|
||
| # Find all ItemGroups with AutoUpdate label | ||
| $autoUpdateGroups = $xml.Project.ItemGroup | Where-Object { | ||
| $null -ne $_.Label -and $_.Label -match 'AutoUpdate' | ||
| } | ||
|
|
||
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | ||
|
|
||
| foreach ($itemGroup in $autoUpdateGroups) { | ||
| $packageVersions = $itemGroup.PackageVersion | ||
|
|
||
| if (-not $packageVersions) { continue } | ||
|
|
||
| if ($EnableVerboseLogging) { | ||
| Write-Host "[VERBOSE] Processing ItemGroup with $(@($packageVersions).Count) packages" |
Copilot
AI
Feb 7, 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.
The repo’s Directory.Packages.props uses the MSBuild XML default namespace (xmlns="http://schemas.microsoft.com/developer/msbuild/2003"). Accessing nodes via $xml.Project.ItemGroup will not find elements under that namespace, so no AutoUpdate ItemGroups will be processed. Update the XML traversal to use an XmlNamespaceManager + SelectNodes (or otherwise handle the default namespace) when locating ItemGroups/PackageVersion elements.
| $updateCount = 0 | |
| # Find all ItemGroups with AutoUpdate label | |
| $autoUpdateGroups = $xml.Project.ItemGroup | Where-Object { | |
| $null -ne $_.Label -and $_.Label -match 'AutoUpdate' | |
| } | |
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | |
| foreach ($itemGroup in $autoUpdateGroups) { | |
| $packageVersions = $itemGroup.PackageVersion | |
| if (-not $packageVersions) { continue } | |
| if ($EnableVerboseLogging) { | |
| Write-Host "[VERBOSE] Processing ItemGroup with $(@($packageVersions).Count) packages" | |
| # Create namespace manager for MSBuild default namespace | |
| $namespaceManager = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) | |
| if ($xml.DocumentElement -and $xml.DocumentElement.NamespaceURI) { | |
| $namespaceManager.AddNamespace("msb", $xml.DocumentElement.NamespaceURI) | |
| } | |
| $updateCount = 0 | |
| # Find all ItemGroups with AutoUpdate label | |
| if ($namespaceManager.HasNamespace("msb")) { | |
| $autoUpdateGroups = $xml.SelectNodes("//msb:ItemGroup[contains(@Label, 'AutoUpdate')]", $namespaceManager) | |
| } else { | |
| # Fallback for documents without a default namespace | |
| $autoUpdateGroups = $xml.SelectNodes("//ItemGroup[contains(@Label, 'AutoUpdate')]") | |
| } | |
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | |
| foreach ($itemGroup in $autoUpdateGroups) { | |
| if ($namespaceManager.HasNamespace("msb")) { | |
| $packageVersions = $itemGroup.SelectNodes("msb:PackageVersion", $namespaceManager) | |
| } else { | |
| # Fallback for documents without a default namespace | |
| $packageVersions = $itemGroup.SelectNodes("PackageVersion") | |
| } | |
| if (-not $packageVersions -or $packageVersions.Count -eq 0) { continue } | |
| if ($EnableVerboseLogging) { | |
| Write-Host "[VERBOSE] Processing ItemGroup with $($packageVersions.Count) packages" |
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>
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.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| $updateCount = 0 | ||
|
|
||
| # Find all ItemGroups with AutoUpdate label | ||
| $autoUpdateGroups = $xml.Project.ItemGroup | Where-Object { | ||
| $null -ne $_.Label -and $_.Label -match 'AutoUpdate' | ||
| } | ||
|
|
||
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | ||
|
|
||
| foreach ($itemGroup in $autoUpdateGroups) { | ||
| $packageVersions = $itemGroup.PackageVersion | ||
|
|
||
| if (-not $packageVersions) { continue } | ||
|
|
||
| if ($EnableVerboseLogging) { | ||
| Write-Host "[VERBOSE] Processing ItemGroup with $(@($packageVersions).Count) packages" |
Copilot
AI
Feb 7, 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.
Directory.Packages.props uses the MSBuild default XML namespace (<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">). With that default namespace, $xml.Project.ItemGroup will not select any nodes, so $autoUpdateGroups will always be empty and the script won’t update anything. Use an XmlNamespaceManager + SelectNodes/SelectSingleNode (or an XPath using local-name()) to find ItemGroup[@Label[contains(.,'AutoUpdate')]]/PackageVersion reliably.
| $updateCount = 0 | |
| # Find all ItemGroups with AutoUpdate label | |
| $autoUpdateGroups = $xml.Project.ItemGroup | Where-Object { | |
| $null -ne $_.Label -and $_.Label -match 'AutoUpdate' | |
| } | |
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | |
| foreach ($itemGroup in $autoUpdateGroups) { | |
| $packageVersions = $itemGroup.PackageVersion | |
| if (-not $packageVersions) { continue } | |
| if ($EnableVerboseLogging) { | |
| Write-Host "[VERBOSE] Processing ItemGroup with $(@($packageVersions).Count) packages" | |
| # Prepare namespace manager for default MSBuild XML namespace (if present) | |
| $nsMgr = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) | |
| if ($xml.DocumentElement -and $xml.DocumentElement.NamespaceURI) { | |
| $nsMgr.AddNamespace("msb", $xml.DocumentElement.NamespaceURI) | |
| } | |
| $updateCount = 0 | |
| # Find all ItemGroups with AutoUpdate label (handle default MSBuild XML namespace) | |
| if ($nsMgr -and $nsMgr.HasNamespace("msb")) { | |
| $autoUpdateGroups = $xml.SelectNodes("//msb:ItemGroup[contains(@Label,'AutoUpdate')]", $nsMgr) | |
| } else { | |
| # Fallback for files without a default namespace | |
| $autoUpdateGroups = $xml.SelectNodes("//ItemGroup[contains(@Label,'AutoUpdate')]") | |
| } | |
| Write-Host "Found $($autoUpdateGroups.Count) ItemGroups with AutoUpdate label" | |
| foreach ($itemGroup in $autoUpdateGroups) { | |
| if ($nsMgr -and $nsMgr.HasNamespace("msb")) { | |
| $packageVersions = $itemGroup.SelectNodes("msb:PackageVersion", $nsMgr) | |
| } else { | |
| $packageVersions = $itemGroup.SelectNodes("PackageVersion") | |
| } | |
| if (-not $packageVersions -or $packageVersions.Count -eq 0) { continue } | |
| if ($EnableVerboseLogging) { | |
| Write-Host "[VERBOSE] Processing ItemGroup with $($packageVersions.Count) packages" |
| # 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 = "" | ||
| if (Test-Path $nugetGithubConfigPath) { | ||
| $configSourceFlag = "--configfile `"$nugetGithubConfigPath`"" | ||
| if ($EnableVerboseLogging) { | ||
| Write-Host " [VERBOSE] Using NuGet-GitHub.Config from: $nugetGithubConfigPath" | ||
| } | ||
| } | ||
| elseif (Test-Path $nugetConfigPath) { | ||
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | ||
| if ($EnableVerboseLogging) { | ||
| Write-Host " [VERBOSE] Using NuGet.config from: $nugetConfigPath" | ||
| } | ||
| } | ||
| else { | ||
| Write-Warning "NuGet-GitHub.Config or NuGet.config not found at: $SourcesDirectory - search may not find required feeds" | ||
| } |
Copilot
AI
Feb 7, 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.
The script looks for NuGet.config (lowercase c), but the repo file is NuGet.Config (capital C). This will fail on case-sensitive filesystems (and also misses the internal feed config locally), causing package search to run without the intended sources. Update the script to check for the actual NuGet.Config name (or probe both casings).
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.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
.github/workflows/package-update.yml:66
- The final
with:block is invalid YAML for arun:step and will cause the workflow to fail to load. If you intend to use a different token, set it viaenv(e.g.,GH_TOKEN) or switch the step to a reusable action that supportswith:inputs; otherwise remove these lines.
| $nugetGithubConfigPath = Join-Path $SourcesDirectory "NuGet-GitHub.Config" | ||
| $nugetConfigPath = Join-Path $SourcesDirectory "NuGet.config" | ||
| $configSourceFlag = "" | ||
| if (Test-Path $nugetGithubConfigPath) { | ||
| $configSourceFlag = "--configfile `"$nugetGithubConfigPath`"" | ||
| if ($EnableVerboseLogging) { | ||
| Write-Host " [VERBOSE] Using NuGet-GitHub.Config from: $nugetGithubConfigPath" | ||
| } | ||
| } | ||
| elseif (Test-Path $nugetConfigPath) { | ||
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | ||
| if ($EnableVerboseLogging) { | ||
| Write-Host " [VERBOSE] Using NuGet.config from: $nugetConfigPath" | ||
| } | ||
| } | ||
| else { | ||
| Write-Warning "NuGet-GitHub.Config or NuGet.config not found at: $SourcesDirectory - search may not find required feeds" | ||
| } |
Copilot
AI
Feb 7, 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.
The repo’s file is NuGet.Config (capital C). On case-sensitive filesystems this Join-Path ... "NuGet.config" check will fail and the script will incorrectly warn that no NuGet config exists. Update the filename to match (NuGet.Config) or check both casings.
This script updates .NET SDK and MSBuild SDK versions in the global.json file by querying the latest releases and modifying the file accordingly.
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.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| git push --set-upstream origin $branch | ||
| echo "has-changes=true" >> $env:GITHUB_OUTPUT | ||
|
|
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.
gh pr create is authenticated with secrets.CREATE_PULLREQUEST, but the repo already uses the built-in secrets.GITHUB_TOKEN in other workflows. If possible, prefer GITHUB_TOKEN (with the existing workflow permissions) to avoid managing an extra secret and to make scheduled runs work out of the box.
| throw $errorMsg | ||
| } else { | ||
| Write-Warning $errorMsg | ||
| exit 1 |
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.
When the props file is missing, the script exits with code 1 even when -FailOnError is $false. This contradicts the parameter description (“logs warnings and continues”) and will fail CI runs unexpectedly. Either treat missing props as a hard error regardless of FailOnError, or honor FailOnError here and continue/return cleanly when it’s $false.
| exit 1 | |
| return |
Remove pull_request trigger from package-update workflow
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.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 9 comments.
| $searchCmd = "dotnet package search `"$PackageId`" --exact-match --format json $prereleaseFlag $configSourceFlag" | ||
|
|
||
| if ($EnableVerboseLogging) { | ||
| Write-Host " [VERBOSE] Executing: $searchCmd" | ||
| } | ||
|
|
||
| Write-Host "Searching for MSBuild SDK: $PackageId" | ||
|
|
||
| $output = Invoke-Expression $searchCmd 2>&1 | Out-String | ||
|
|
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.
Avoid Invoke-Expression for running the dotnet command; it’s susceptible to argument injection/quoting bugs and makes error handling harder. Prefer invoking dotnet directly with an argument array and capture stdout/stderr explicitly.
| - name: Open PR with gh | ||
| if: steps.commit.outputs.has-changes == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ secrets.CREATE_PULLREQUEST }} |
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.
This workflow requires a custom secret (secrets.CREATE_PULLREQUEST) to authenticate gh. If possible, prefer the built-in GITHUB_TOKEN (with the pull-requests: write permission already granted above) to avoid managing a PAT/secret and reduce risk of workflow failure when the secret is missing/rotated.
| GH_TOKEN: ${{ secrets.CREATE_PULLREQUEST }} | |
| GH_TOKEN: ${{ github.token }} |
| [Parameter(Mandatory = $false)] | ||
| [string]$SourcesDirectory = $env:BUILD_SOURCESDIRECTORY, | ||
|
|
||
| [Parameter(Mandatory = $false)] | ||
| [bool]$FailOnError = $false | ||
| ) |
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.
$SourcesDirectory defaults to $env:BUILD_SOURCESDIRECTORY, which is usually unset on GitHub Actions. In this workflow the script is invoked without -SourcesDirectory, so Join-Path $SourcesDirectory ... will throw. Add the same fallback logic as Update-NuGetPackageVersions.ps1 (use $env:GITHUB_WORKSPACE / current directory) or change the default to prefer $env:GITHUB_WORKSPACE.
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.
@copilot open a new pull request to apply changes based on this feedback
| # Auto-detect verbose logging from Azure Pipelines System.Debug variable | ||
| $EnableVerboseLogging = ($env:SYSTEM_DEBUG -eq 'true') -or ($env:SYSTEM_DEBUG -eq '1') | ||
|
|
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.
The script gates its own "[VERBOSE]" logging on SYSTEM_DEBUG, but the workflow calls it with -Verbose. As written, -Verbose won’t enable these messages (since the script uses Write-Host rather than Write-Verbose). Consider aligning behavior by detecting the -Verbose common parameter (like the NuGet script does) and/or switching verbose output to Write-Verbose.
| on: | ||
| schedule: | ||
| - cron: "0 6 * * 1" | ||
|
|
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.
The workflow file only defines a scheduled trigger, but the PR description says it also runs on pull requests to main. Either add a pull_request trigger (and ensure permissions/push behavior works for PRs) or update the PR description to match the actual triggers.
| - name: Run PowerShell script | ||
| shell: pwsh | ||
| run: | | ||
| ./.github/scripts/Update-NuGetPackageVersions.ps1 -Verbose | ||
|
|
||
| - name: Run PowerShell script | ||
| shell: pwsh | ||
| run: | | ||
| ./.github/scripts/Update-DotNetSdkVersions.ps1 -Verbose | ||
|
|
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.
Both steps are named "Run PowerShell script", which makes workflow logs harder to read and diagnose. Rename these steps to reflect which script is being executed (NuGet packages vs .NET SDK).
| # 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.
The repo config file is NuGet.Config (capital C), but this script looks for NuGet.config. On case-sensitive filesystems this will fail to find the config and may cause dotnet package search to miss required feeds. Update the filename to match the repo's NuGet.Config casing (and consider checking for NuGet-GitHub.Config first, like the other script).
| # 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 for NuGet configuration files in the sources directory | |
| $configSourceFlag = "" | |
| # Prefer a GitHub-specific config if present, fall back to the repo-wide NuGet.Config | |
| $nugetGitHubConfigPath = Join-Path $SourcesDirectory "NuGet-GitHub.Config" | |
| if (Test-Path $nugetGitHubConfigPath) { | |
| $configSourceFlag = "--configfile `"$nugetGitHubConfigPath`"" | |
| if ($EnableVerboseLogging) { | |
| Write-Host " [VERBOSE] Using NuGet-GitHub.Config from: $nugetGitHubConfigPath" | |
| } | |
| } | |
| else { | |
| $nugetConfigPath = Join-Path $SourcesDirectory "NuGet.Config" | |
| if (Test-Path $nugetConfigPath) { | |
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | |
| if ($EnableVerboseLogging) { | |
| Write-Host " [VERBOSE] Using NuGet.Config from: $nugetConfigPath" | |
| } | |
| } | |
| else { | |
| Write-Warning "NuGet-GitHub.Config or NuGet.Config not found under: $SourcesDirectory - search may not find private feeds" | |
| } | |
| } |
| # 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 = "" | ||
| if (Test-Path $nugetGithubConfigPath) { | ||
| $configSourceFlag = "--configfile `"$nugetGithubConfigPath`"" | ||
| if ($EnableVerboseLogging) { | ||
| Write-Host " [VERBOSE] Using NuGet-GitHub.Config from: $nugetGithubConfigPath" | ||
| } | ||
| } | ||
| elseif (Test-Path $nugetConfigPath) { | ||
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | ||
| if ($EnableVerboseLogging) { | ||
| Write-Host " [VERBOSE] Using NuGet.config from: $nugetConfigPath" | ||
| } | ||
| } |
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.
The repo config file is NuGet.Config (capital C), but this script falls back to NuGet.config. On case-sensitive filesystems that fallback won't be found. Change the fallback to NuGet.Config to match the repo root file name.
* Initial plan * Add run_attempt to branch name and concurrency group to prevent collisions Co-authored-by: neilr81 <49037171+neilr81@users.noreply.github.com> * Enable cancellation of in-progress package updates --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: neilr81 <49037171+neilr81@users.noreply.github.com>
…DotNetSdkVersions.ps1 (#826) * Initial plan * Add fallback logic for SourcesDirectory in Update-DotNetSdkVersions.ps1 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>
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.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 10 comments.
| Write-Host "##[section]Saving $updateCount SDK updates to $globalJsonFile" | ||
|
|
||
| # Save with consistent JSON formatting (2-space indent) | ||
| $globalJson | ConvertTo-Json -Depth 10 | Set-Content $globalJsonFile -NoNewline |
Copilot
AI
Feb 10, 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.
Using Set-Content with -NoNewline will remove the trailing newline from global.json, which differs from the current file format (which has a trailing newline at line 7). This can cause unnecessary git diffs and may not follow POSIX conventions. Consider adding a newline after the JSON content, or use Out-File with explicit encoding to maintain the original format. For example: '$globalJson | ConvertTo-Json -Depth 10 | Set-Content $globalJsonFile' (without -NoNewline) or append "`n" to ensure a trailing newline.
| $globalJson | ConvertTo-Json -Depth 10 | Set-Content $globalJsonFile -NoNewline | |
| $globalJson | ConvertTo-Json -Depth 10 | Set-Content $globalJsonFile |
| 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 | ||
| } |
Copilot
AI
Feb 10, 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.
The function Get-LatestVersionFromString (lines 90-131) is duplicated identically in Update-NuGetPackageVersions.ps1 (lines 89-130). Similarly, Test-PreReleaseVersion is duplicated in both scripts. Consider extracting these shared utility functions into a common PowerShell module (e.g., .github/scripts/VersionUtils.psm1) and dot-sourcing or importing it in both scripts. This reduces maintenance burden and ensures consistent behavior. The comment at line 88 of Update-NuGetPackageVersions.ps1 already suggests this was intended ('from VersionUtils.ps1').
| - name: Open PR with gh | ||
| if: steps.commit.outputs.has-changes == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ secrets.CREATE_PULLREQUEST }} |
Copilot
AI
Feb 10, 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.
The workflow uses a custom secret 'CREATE_PULLREQUEST' for the GH_TOKEN, but the workflow already declares 'contents: write' and 'pull-requests: write' permissions at the top level (lines 7-9), which should be sufficient for the 'gh pr create' command. Using the built-in GITHUB_TOKEN (via 'secrets.GITHUB_TOKEN') would be more secure and eliminate the need for managing a separate custom secret, unless there's a specific requirement for the PR to trigger other workflows (which the default GITHUB_TOKEN intentionally prevents to avoid recursive workflow triggers). If recursive triggers are needed, this should be documented; otherwise, use 'secrets.GITHUB_TOKEN'.
| GH_TOKEN: ${{ secrets.CREATE_PULLREQUEST }} | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
| --label automation ` | ||
| --assignee "${{ github.actor }}" |
Copilot
AI
Feb 10, 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.
For scheduled workflow runs (triggered by cron), github.actor may not represent a meaningful user to assign the PR to - it will typically be the repository owner or the last person who edited the workflow file. Consider removing the --assignee flag for scheduled runs, or use a specific team/user designation. Alternatively, conditionally set the assignee only when the workflow is triggered by a user action (not by schedule).
| --label automation ` | |
| --assignee "${{ github.actor }}" | |
| --label automation |
| exit 0 | ||
| } | ||
|
|
||
| git commit -m "chore(automation): apply PowerShell updates" |
Copilot
AI
Feb 10, 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.
The commit message 'chore(automation): apply PowerShell updates' is misleading - the scripts are updating NuGet packages and .NET SDK versions, not updating PowerShell itself. Consider a more accurate message like 'chore(automation): update NuGet packages and .NET SDK versions' or 'chore(deps): update package and SDK versions'.
| git commit -m "chore(automation): apply PowerShell updates" | |
| git commit -m "chore(automation): update NuGet packages and .NET SDK versions" |
| # PowerShell Core: Get final URL from response object | ||
| $finalUrl = $response.BaseResponse.RequestMessage.RequestUri.AbsoluteUri | ||
|
|
Copilot
AI
Feb 10, 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.
The code assumes PowerShell Core/7+ by accessing $response.BaseResponse.RequestMessage.RequestUri.AbsoluteUri, which may not work correctly in Windows PowerShell 5.1. For PowerShell 5.1 compatibility, you should check $PSVersionTable.PSVersion and handle the redirect URL extraction differently (using $response.Headers.Location or ResponseUri). However, since the workflow uses 'shell: pwsh' (PowerShell Core), and the script is intended for CI/CD environments, this may be acceptable if documented. Consider adding a comment noting the PowerShell Core requirement, or add version detection for broader compatibility.
| # PowerShell Core: Get final URL from response object | |
| $finalUrl = $response.BaseResponse.RequestMessage.RequestUri.AbsoluteUri | |
| # Determine final URL from response object in a way that works in both | |
| # PowerShell Core and Windows PowerShell 5.1. | |
| $finalUrl = $null | |
| # Preferred (PowerShell Core): RequestMessage.RequestUri | |
| if ($response.BaseResponse -and | |
| $response.BaseResponse.RequestMessage -and | |
| $response.BaseResponse.RequestMessage.RequestUri) { | |
| $finalUrl = $response.BaseResponse.RequestMessage.RequestUri.AbsoluteUri | |
| } | |
| # Fallback: Location header (some environments expose final URI here) | |
| if (-not $finalUrl -and $response.Headers -and $response.Headers.Location) { | |
| $finalUrl = $response.Headers.Location.ToString() | |
| } | |
| # Fallback (Windows PowerShell 5.1): BaseResponse.ResponseUri | |
| if (-not $finalUrl -and | |
| $response.BaseResponse -and | |
| $response.BaseResponse.ResponseUri) { | |
| $finalUrl = $response.BaseResponse.ResponseUri.AbsoluteUri | |
| } | |
| # Auto-detect verbose logging from Azure Pipelines System.Debug variable | ||
| $EnableVerboseLogging = ($env:SYSTEM_DEBUG -eq 'true') -or ($env:SYSTEM_DEBUG -eq '1') |
Copilot
AI
Feb 10, 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.
The verbose logging configuration is inconsistent with Update-NuGetPackageVersions.ps1 and does not respect the -Verbose parameter from CmdletBinding. The script should check if the -Verbose parameter was explicitly passed (using $PSBoundParameters.ContainsKey('Verbose')) before falling back to SYSTEM_DEBUG, similar to how Update-NuGetPackageVersions.ps1 handles it at lines 80-85. This means verbose logging won't work when -Verbose is passed to the script, as shown in the workflow at line 37.
| # Auto-detect verbose logging from Azure Pipelines System.Debug variable | |
| $EnableVerboseLogging = ($env:SYSTEM_DEBUG -eq 'true') -or ($env:SYSTEM_DEBUG -eq '1') | |
| # Determine verbose logging: | |
| # 1. Prefer explicit -Verbose parameter (from CmdletBinding/common parameters) | |
| # 2. Fall back to Azure Pipelines System.Debug variable | |
| if ($PSBoundParameters.ContainsKey('Verbose')) { | |
| $EnableVerboseLogging = [bool]$PSBoundParameters['Verbose'] | |
| } | |
| else { | |
| $EnableVerboseLogging = ($env:SYSTEM_DEBUG -eq 'true') -or ($env:SYSTEM_DEBUG -eq '1') | |
| } |
| # 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 10, 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.
The NuGet configuration file name check uses incorrect casing. The repository has files named 'NuGet.Config' and 'NuGet-GitHub.Config' (capital 'C'), not 'NuGet.config'. On case-sensitive file systems (Linux, macOS), this Test-Path check will fail, causing the script to skip the config file and potentially fail to find packages in private feeds. The script should check for 'NuGet-GitHub.Config' first (as preferred on GitHub runners), then fall back to 'NuGet.Config', matching the pattern used in Update-NuGetPackageVersions.ps1 at lines 148-165.
| # 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 for NuGet configuration in the sources directory | |
| $nugetConfigPathGitHub = Join-Path $SourcesDirectory "NuGet-GitHub.Config" | |
| $nugetConfigPathDefault = Join-Path $SourcesDirectory "NuGet.Config" | |
| $nugetConfigPath = $null | |
| if (Test-Path $nugetConfigPathGitHub) { | |
| $nugetConfigPath = $nugetConfigPathGitHub | |
| } | |
| elseif (Test-Path $nugetConfigPathDefault) { | |
| $nugetConfigPath = $nugetConfigPathDefault | |
| } | |
| $configSourceFlag = "" | |
| if ($nugetConfigPath) { | |
| $configSourceFlag = "--configfile `"$nugetConfigPath`"" | |
| if ($EnableVerboseLogging) { | |
| Write-Host " [VERBOSE] Using NuGet configuration from: $nugetConfigPath" | |
| } | |
| } | |
| else { | |
| Write-Warning "NuGet configuration file not found (expected NuGet-GitHub.Config or NuGet.Config in $SourcesDirectory) - search may not find private feeds" | |
| } |
| on: | ||
| schedule: | ||
| - cron: "0 6 * * 1" |
Copilot
AI
Feb 10, 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.
The PR description states the workflow should run "on pull requests to the main branch", but the workflow only has a schedule trigger (weekly on Mondays at 6:00 UTC). If the intent is to also test the workflow on pull requests, add a pull_request trigger with appropriate path filters to avoid unnecessary runs. If PR-based triggers are not needed, the PR description should be updated to reflect the actual behavior.
| throw $errorMsg | ||
| } else { | ||
| Write-Warning $errorMsg | ||
| exit 1 |
Copilot
AI
Feb 10, 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.
When FailOnError is false, the script should not exit with a non-zero exit code. The current logic writes a warning but still exits with code 1, which will cause the GitHub Actions workflow to fail even when FailOnError is set to false. Either remove the 'exit 1' statement when FailOnError is false, or exit with code 0. This same issue exists in Update-NuGetPackageVersions.ps1 at line 256.
| exit 1 | |
| exit 0 |
This pull request introduces a new automated workflow for keeping NuGet package versions up to date. It adds a PowerShell script to scan and update package versions in the
Directory.Packages.propsfile and a GitHub Actions workflow to run this script weekly and on pull requests to themainbranch. The workflow commits any changes and opens a pull request automatically if updates are found.Automation for NuGet package updates:
.github/scripts/Update-NuGetPackageVersions.ps1, a PowerShell script that:Directory.Packages.propsforPackageVersionentries inItemGroupslabeledAutoUpdatedotnet package searchPreserveMajorattribute and pre-release versionsGitHub Actions workflow for scheduled and PR-based updates:
.github/workflows/package-update.ymlto:main