diff --git a/.github/scripts/Update-DotNetSdkVersions.ps1 b/.github/scripts/Update-DotNetSdkVersions.ps1 new file mode 100644 index 000000000..0cd8725c2 --- /dev/null +++ b/.github/scripts/Update-DotNetSdkVersions.ps1 @@ -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//dotnet-sdk--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" + } + + $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 + + if ($LASTEXITCODE -ne 0) { + $errorMsg = "Failed to search for package '$PackageId': $output" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + return $null + } + } + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Raw output: $output" + } + + $result = $output | ConvertFrom-Json + + if (-not $result.searchResult -or $result.searchResult.Count -eq 0) { + $errorMsg = "Package '$PackageId' not found in any configured feed" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + return $null + } + } + + # Iterate through all sources and packages to find the latest version + # The JSON structure is: searchResult[].packages[].version + $latestVersion = $null + foreach ($source in $result.searchResult) { + if ($source.packages) { + foreach ($package in $source.packages) { + if ($package.id -eq $PackageId) { + $latestVersion = Get-LatestVersionFromString -First $latestVersion -Second $package.version + } + } + } + } + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Found latest version: $latestVersion" + } + + return $latestVersion + } + catch { + $errorMsg = "Error searching for package '$PackageId': $_" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + return $null + } + } +} + +# Main script execution +Write-Host "===============================================================================" +Write-Host ".NET SDK Version Update Script" +Write-Host "===============================================================================" +Write-Host "Global JSON Path: $GlobalJsonPath" +Write-Host "SDK Channel: $SdkChannel" +Write-Host "Sources Directory: $SourcesDirectory" +Write-Host "Verbose Logging: $EnableVerboseLogging" +Write-Host "Fail On Error: $FailOnError" +Write-Host "===============================================================================" + +$globalJsonFile = Join-Path $SourcesDirectory $GlobalJsonPath +Write-Host "Full path to global.json: $globalJsonFile" + +if (-not (Test-Path $globalJsonFile)) { + $errorMsg = "global.json file not found at: $globalJsonFile" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + exit 1 + } +} + +Write-Host "Updating SDK versions in: $globalJsonFile" +Write-Host "Using SDK channel: $SdkChannel" + +# Load global.json +$globalJson = Get-Content $globalJsonFile -Raw | ConvertFrom-Json + +if ($EnableVerboseLogging) { + Write-Host "[VERBOSE] Loaded global.json content:" + Write-Host ($globalJson | ConvertTo-Json -Depth 10) +} + +$updateCount = 0 + +# Update .NET SDK version +$currentSdkVersion = $globalJson.sdk.version +Write-Host "Current .NET SDK version: $currentSdkVersion" + +$latestSdkVersion = Get-LatestSdkVersion -Channel $SdkChannel + +if ($latestSdkVersion) { + $selectedVersion = Get-LatestVersionFromString -First $currentSdkVersion -Second $latestSdkVersion + + if ($EnableVerboseLogging) { + Write-Host "[VERBOSE] SDK version comparison: current=$currentSdkVersion, latest=$latestSdkVersion, selected=$selectedVersion" + } + + if ($selectedVersion -ne $currentSdkVersion) { + Write-Host "##[section]Updating .NET SDK from '$currentSdkVersion' to '$latestSdkVersion'" + $globalJson.sdk.version = $latestSdkVersion + $updateCount++ + } else { + Write-Host ".NET SDK already at latest version '$currentSdkVersion'" + } +} + +# Update MSBuild SDKs +if ($globalJson.'msbuild-sdks') { + $msbuildSdks = $globalJson.'msbuild-sdks' + + if ($EnableVerboseLogging) { + Write-Host "[VERBOSE] Found $($msbuildSdks.PSObject.Properties.Count) MSBuild SDK(s) to check" + } + + foreach ($property in $msbuildSdks.PSObject.Properties) { + $packageName = $property.Name + $currentVersion = $property.Value + + Write-Host "Checking MSBuild SDK: $packageName (current: $currentVersion)" + + $includePrerelease = Test-PreReleaseVersion -Version $currentVersion + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Include prerelease: $includePrerelease" + } + + $latestVersion = Get-LatestPackageVersion -PackageId $packageName -IncludePrerelease $includePrerelease + + if (-not $latestVersion) { + Write-Host "No update available for '$packageName'" + continue + } + + $selectedVersion = Get-LatestVersionFromString -First $currentVersion -Second $latestVersion + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Version comparison: current=$currentVersion, latest=$latestVersion, selected=$selectedVersion" + } + + if ($selectedVersion -ne $currentVersion) { + Write-Host "##[section]Updating MSBuild SDK '$packageName' from '$currentVersion' to '$latestVersion'" + $msbuildSdks.$packageName = $latestVersion + $updateCount++ + } else { + Write-Host "MSBuild SDK '$packageName' already at latest version '$currentVersion'" + } + } +} + +if ($updateCount -gt 0) { + 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 + Write-Host "Successfully updated $updateCount SDK(s)" +} else { + Write-Host "No SDK updates needed" +} + +Write-Host "===============================================================================" +Write-Host ".NET SDK Update Complete" +Write-Host "===============================================================================" diff --git a/.github/scripts/Update-NuGetPackageVersions.ps1 b/.github/scripts/Update-NuGetPackageVersions.ps1 new file mode 100644 index 000000000..491c8f93d --- /dev/null +++ b/.github/scripts/Update-NuGetPackageVersions.ps1 @@ -0,0 +1,350 @@ +<# +.SYNOPSIS + Updates NuGet package versions in Directory.Packages.props file. + +.DESCRIPTION + Scans Directory.Packages.props for PackageVersion elements in ItemGroups labeled 'AutoUpdate', + queries the latest available versions using 'dotnet package search', and updates the Version + attributes accordingly. Respects PreserveMajor attribute and pre-release version detection. + +.PARAMETER PropsFilePath + Relative path to the Directory.Packages.props file from the source directory. + Default: "Directory.Packages.props" + +.PARAMETER SourcesDirectory + The root source directory containing the props file. + Default: $env:BUILD_SOURCESDIRECTORY (Azure Pipelines variable) + +.PARAMETER FailOnError + If $true, throws an exception on package 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-NuGetPackageVersions.ps1 + +.EXAMPLE + .\Update-NuGetPackageVersions.ps1 -PropsFilePath "Directory.Packages.props" -FailOnError $true + +.EXAMPLE + $env:SYSTEM_DEBUG = 'true'; .\Update-NuGetPackageVersions.ps1 +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory = $false)] + [string]$PropsFilePath = "Directory.Packages.props", + + [Parameter(Mandatory = $false)] + [string]$SourcesDirectory = $( + if ($env:BUILD_SOURCESDIRECTORY) { + $env:BUILD_SOURCESDIRECTORY + } + elseif ($env:GITHUB_WORKSPACE) { + $env:GITHUB_WORKSPACE + } + else { + (Get-Location).Path + } + ), + + [Parameter(Mandatory = $false)] + [bool]$FailOnError = $false +) + +# Normalize and validate SourcesDirectory so it is always a valid root directory +if ([string]::IsNullOrWhiteSpace($SourcesDirectory)) { + # GitHub Actions default + $SourcesDirectory = $env:GITHUB_WORKSPACE +} + +if ([string]::IsNullOrWhiteSpace($SourcesDirectory)) { + # Local or generic PowerShell fallback + $SourcesDirectory = (Get-Location).Path +} + +if (-not (Test-Path -LiteralPath $SourcesDirectory -PathType Container)) { + throw "SourcesDirectory '$SourcesDirectory' does not exist or is not a directory. Specify a valid -SourcesDirectory path." +} + +# Resolve to a fully qualified, normalized path +$SourcesDirectory = (Resolve-Path -LiteralPath $SourcesDirectory).ProviderPath +# Determine whether verbose logging should be enabled: +# - Prefer the standard -Verbose common parameter when explicitly passed +# - Fall back to Azure Pipelines System.Debug variable for backwards compatibility +$isVerboseParameterSet = $PSBoundParameters.ContainsKey('Verbose') -and $PSBoundParameters['Verbose'] +$EnableVerboseLogging = $isVerboseParameterSet -or ($env:SYSTEM_DEBUG -eq 'true') -or ($env:SYSTEM_DEBUG -eq '1') + +if ($EnableVerboseLogging) { + $VerbosePreference = 'Continue' +} +$ErrorActionPreference = if ($FailOnError) { "Stop" } else { "Continue" } + +# Helper function for version comparison (from VersionUtils.ps1) +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-LatestPackageVersion { + param ( + [string]$PackageId, + [bool]$IncludePrerelease, + [string]$MajorVersion = "" + ) + + try { + $prereleaseFlag = if ($IncludePrerelease) { "--prerelease" } else { "" } + + # 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" + } + + $searchCmd = "dotnet package search `"$PackageId`" --exact-match --format json $prereleaseFlag $configSourceFlag" + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Executing: $searchCmd" + } + + Write-Host ("Searching for package: {0} {1}" -f $PackageId, ($MajorVersion ? ('(major version {0}.*)' -f $MajorVersion) : '')) + + $output = Invoke-Expression $searchCmd 2>&1 | Out-String + + if ($LASTEXITCODE -ne 0) { + $errorMsg = "Failed to search for package '$PackageId': $output" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + return $null + } + } + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Raw output: $output" + } + + $result = $output | ConvertFrom-Json + + if (-not $result.searchResult -or $result.searchResult.Count -eq 0) { + $errorMsg = "Package '$PackageId' not found in any configured feed" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + return $null + } + } + + # Iterate through all sources and packages to find the latest version + # The JSON structure is: searchResult[].packages[].version + $latestVersion = $null + foreach ($source in $result.searchResult) { + if ($source.packages) { + foreach ($package in $source.packages) { + if ($package.id -eq $PackageId) { + # If major version filtering is needed, skip non-matching versions + if ($MajorVersion -and -not ($package.version -match "^$MajorVersion\.")) { + continue + } + $latestVersion = Get-LatestVersionFromString -First $latestVersion -Second $package.version + } + } + } + } + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Found latest version: $latestVersion" + } + + return $latestVersion + } + catch { + $errorMsg = "Error searching for package '$PackageId': $_" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + return $null + } + } +} + +# Main script execution +Write-Host "===============================================================================" +Write-Host "NuGet Package Version Update Script" +Write-Host "===============================================================================" +Write-Host "Props File Path: $PropsFilePath" +Write-Host "Sources Directory: $SourcesDirectory" +Write-Host "Verbose Logging: $EnableVerboseLogging" +Write-Host "Fail On Error: $FailOnError" +Write-Host "===============================================================================" + +$propsFile = Join-Path $SourcesDirectory $PropsFilePath +Write-Host "Full path to props file: $propsFile" + +if (-not (Test-Path $propsFile)) { + $errorMsg = "Props file not found at: $propsFile" + if ($FailOnError) { + throw $errorMsg + } else { + Write-Warning $errorMsg + exit 1 + } +} + +Write-Host "Updating NuGet packages in: $propsFile" + +# Load XML with whitespace preservation +$xml = New-Object System.Xml.XmlDocument +$xml.PreserveWhitespace = $true +$xml.Load($propsFile) + +$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" + } + + foreach ($packageVersion in $packageVersions) { + $packageId = $packageVersion.Include + $currentVersion = $packageVersion.Version + $preserveMajor = $packageVersion.PreserveMajor -eq "true" + + if (-not $packageId -or -not $currentVersion) { + Write-Host "Skipping invalid PackageVersion: $($packageVersion.OuterXml)" + continue + } + + if ($EnableVerboseLogging) { + Write-Host "[VERBOSE] Processing: $packageId (current: $currentVersion, preserveMajor: $preserveMajor)" + } + + # Determine if we should include prerelease + $includePrerelease = Test-PreReleaseVersion -Version $currentVersion + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Include prerelease: $includePrerelease" + } + + # Get major version if needed + $majorVersion = "" + if ($preserveMajor) { + $majorVersion = $currentVersion.Split('.')[0] + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Preserving major version: $majorVersion" + } + } + + # Get latest version + $latestVersion = Get-LatestPackageVersion -PackageId $packageId -IncludePrerelease $includePrerelease -MajorVersion $majorVersion + + if (-not $latestVersion) { + Write-Host "No update available for '$packageId'" + continue + } + + # Compare versions + $selectedVersion = Get-LatestVersionFromString -First $currentVersion -Second $latestVersion + + if ($EnableVerboseLogging) { + Write-Host " [VERBOSE] Version comparison: current=$currentVersion, latest=$latestVersion, selected=$selectedVersion" + } + + if ($selectedVersion -ne $currentVersion) { + Write-Host "##[section]Updating '$packageId' from '$currentVersion' to '$latestVersion'" + $packageVersion.Version = $latestVersion + $updateCount++ + } else { + Write-Host "Package '$packageId' already at latest version '$currentVersion'" + } + } +} + +if ($updateCount -gt 0) { + Write-Host "##[section]Saving $updateCount package updates to $propsFile" + $xml.Save($propsFile) + Write-Host "Successfully updated $updateCount packages" +} else { + Write-Host "No package updates needed" +} + +Write-Host "===============================================================================" +Write-Host "NuGet Package Update Complete" +Write-Host "===============================================================================" diff --git a/.github/workflows/package-update.yml b/.github/workflows/package-update.yml new file mode 100644 index 000000000..5ce7ef256 --- /dev/null +++ b/.github/workflows/package-update.yml @@ -0,0 +1,65 @@ +name: Package Updates (GitHub) + +on: + schedule: + - cron: "0 6 * * 1" + pull_request: + branches: [ "main" ] + +permissions: + contents: write + pull-requests: write + +jobs: + run-script-and-pr: + runs-on: windows-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Install .NET 10 SDK + uses: actions/setup-dotnet@v5 + with: + dotnet-version: '10.0.x' + + - name: Run PowerShell script + shell: pwsh + run: | + ./.github/scripts/Update-NuGetPackageVersions.ps1 -Verbose + + - name: Create branch, commit, push + id: commit + shell: pwsh + run: | + $branch = "automation/package-update-${{ github.run_id }}" + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git checkout -b $branch + git add -A + + if (git diff --cached --quiet) { + echo "No changes detected; skipping commit and PR creation." + echo "has-changes=false" >> $env:GITHUB_OUTPUT + exit 0 + } + + git commit -m "chore(automation): apply PowerShell updates" + git push --set-upstream origin $branch + echo "has-changes=true" >> $env:GITHUB_OUTPUT + + - name: Open PR with gh + if: steps.commit.outputs.has-changes == 'true' + env: + GH_TOKEN: ${{ secrets.CREATE_PULLREQUEST }} + shell: pwsh + run: | + gh pr create ` + --title "Automated Package Update" ` + --body "This PR was created automatically by the workflow run ${{ github.run_id }}." ` + --base main ` + --head "automation/package-update-${{ github.run_id }}" ` + --label automation ` + --assignee "${{ github.actor }}" diff --git a/Directory.Packages.props b/Directory.Packages.props index d869372b4..070aaf357 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,59 +1,59 @@ - + true true - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - + + - + - - + + - + @@ -67,7 +67,7 @@ - +