diff --git a/.github/workflows/vendor.yml b/.github/workflows/vendor.yml index ea7085a..14fa7ed 100644 --- a/.github/workflows/vendor.yml +++ b/.github/workflows/vendor.yml @@ -57,6 +57,9 @@ jobs: Set-GHVariable -Name COUNT_UPDATED -Value $count $newVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json) + # Source utility functions + . scripts/utils.ps1 + $listUpdated = "" $updateMessage = "| Name | Old Version | New Version |`n| :--- | :---: | :---: |`n" $majorUpdates = @() @@ -75,46 +78,11 @@ jobs: $singleDepNewVersion = $s.version } - # Determine change type and emoji - $changeType = "unknown" - $emoji = "🔄" - $isMajor = $false - try { - # Handle versions with more than 4 parts - $oldVerStr = $oldVersion.Split('-')[0] - $newVerStr = $s.version.Split('-')[0] - - # Split by dots and take only numeric parts, first 4 max - $oldParts = $oldVerStr.Split('.') | Where-Object { $_ -match '^\d+$' } | Select-Object -First 4 - $newParts = $newVerStr.Split('.') | Where-Object { $_ -match '^\d+$' } | Select-Object -First 4 - - # Ensure we have at least 2 parts (major.minor) - if ($oldParts.Count -ge 2 -and $newParts.Count -ge 2) { - $oldVerParseable = $oldParts -join '.' - $newVerParseable = $newParts -join '.' - - $oldVer = [System.Version]::Parse($oldVerParseable) - $newVer = [System.Version]::Parse($newVerParseable) - - if ($newVer.Major -gt $oldVer.Major) { - $changeType = "major" - $emoji = "🔥" - $isMajor = $true - } elseif ($newVer.Minor -gt $oldVer.Minor) { - $changeType = "minor" - $emoji = "🚀" - } elseif ($newVer -gt $oldVer) { - $changeType = "patch" - $emoji = "⬆️" - } else { - $changeType = "unknown" - $emoji = "🔄" - } - } - } catch { - $changeType = "unknown" - $emoji = "🔄" - } + # Determine change type and emoji using shared function + $result = Get-VersionChangeType -OldVersion $oldVersion -NewVersion $s.version + $changeType = $result.ChangeType + $emoji = $result.Emoji + $isMajor = $result.IsMajor # Track major updates for changelog section if ($isMajor) { @@ -229,18 +197,26 @@ jobs: # Commit the changes git add vendor/sources.json $commitResult = git commit -m "⬆️ Update dependencies ($env:LIST_UPDATED)" + $commitSuccess = $LASTEXITCODE -eq 0 - if ($commitResult) { + if ($commitSuccess) { # Push directly to master git push origin HEAD:master + $pushSuccess = $LASTEXITCODE -eq 0 - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "✅ **Success!** Updates have been automatically merged to master." >> $env:GITHUB_STEP_SUMMARY - echo "" >> $env:GITHUB_STEP_SUMMARY - echo "**Updated dependencies:** $env:LIST_UPDATED" >> $env:GITHUB_STEP_SUMMARY + if ($pushSuccess) { + echo "" >> $env:GITHUB_STEP_SUMMARY + echo "✅ **Success!** Updates have been automatically merged to master." >> $env:GITHUB_STEP_SUMMARY + echo "" >> $env:GITHUB_STEP_SUMMARY + echo "**Updated dependencies:** $env:LIST_UPDATED" >> $env:GITHUB_STEP_SUMMARY - # Set a flag to skip PR creation - echo "AUTO_MERGED=true" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + # Set a flag to skip PR creation + echo "AUTO_MERGED=true" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 + } else { + throw "Failed to push to master (exit code: $LASTEXITCODE)" + } + } else { + throw "Failed to commit changes (exit code: $LASTEXITCODE)" } } catch { echo "" >> $env:GITHUB_STEP_SUMMARY @@ -252,9 +228,16 @@ jobs: Write-Warning "Failed to auto-merge: $($_.Exception.Message)" - # Reset the commit if one was made - if ($commitResult) { - git reset --hard HEAD~1 + # Only reset if commit was successful but push failed + if ($commitSuccess -and -not $pushSuccess) { + try { + git reset --hard HEAD~1 + if ($LASTEXITCODE -ne 0) { + Write-Warning "Failed to reset commit (exit code: $LASTEXITCODE), continuing with PR creation" + } + } catch { + Write-Warning "Failed to reset commit: $($_.Exception.Message), continuing with PR creation" + } } # Set flag to create PR instead @@ -262,7 +245,7 @@ jobs: } - uses: peter-evans/create-pull-request@v8 - if: env.COUNT_UPDATED > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false') + if: fromJSON(env.COUNT_UPDATED) > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false') with: title: ${{ env.COUNT_UPDATED == 1 && format('⬆️ Update {0}', env.LIST_UPDATED) || format('⬆️ Update {0} vendored dependencies', env.COUNT_UPDATED) }} body: | diff --git a/scripts/update.ps1 b/scripts/update.ps1 index 0564ea5..7da623a 100644 --- a/scripts/update.ps1 +++ b/scripts/update.ps1 @@ -304,47 +304,15 @@ foreach ($s in $sources) { $count++ - # Analyze version change type - $changeType = "unknown" - try { - # Try parsing as semantic version - # Handle versions with more than 4 parts by taking only the first 3-4 parts - $oldVerStr = $s.version.Split('-')[0] - $newVerStr = $version.Split('-')[0] - - # Split by dots and take only numeric parts, first 4 max - $oldParts = $oldVerStr.Split('.') | Where-Object { $_ -match '^\d+$' } | Select-Object -First 4 - $newParts = $newVerStr.Split('.') | Where-Object { $_ -match '^\d+$' } | Select-Object -First 4 - - # Ensure we have at least 2 parts (major.minor) - if ($oldParts.Count -ge 2 -and $newParts.Count -ge 2) { - $oldVerParseable = $oldParts -join '.' - $newVerParseable = $newParts -join '.' - - $oldVer = [System.Version]::Parse($oldVerParseable) - $newVer = [System.Version]::Parse($newVerParseable) - - if ($newVer -lt $oldVer) { - $changeType = "downgrade" - $hasBreakingChanges = $true - } elseif ($newVer.Major -gt $oldVer.Major) { - $changeType = "major" - $hasBreakingChanges = $true - } elseif ($newVer.Minor -gt $oldVer.Minor) { - $changeType = "minor" - } elseif ($newVer.Build -gt $oldVer.Build) { - $changeType = "patch" - } else { - # No version increase detected (could be equal or non-incremental change) - $changeType = "unknown" - } - } else { - # Not enough numeric parts for semantic versioning - throw "Not enough numeric version parts" - } - } catch { - # If semantic versioning fails, treat as unknown (potentially breaking) - $changeType = "unknown" + # Analyze version change type using shared function + $result = Get-VersionChangeType -OldVersion $s.version -NewVersion $version + $changeType = $result.ChangeType + + # Determine if this is a breaking change + if ($changeType -eq "downgrade" -or $changeType -eq "major") { + $hasBreakingChanges = $true + } elseif ($changeType -eq "unknown") { + # If version parsing failed, treat as potentially breaking $hasBreakingChanges = $true Write-Verbose "Could not parse version as semantic version for dependency '$($s.name)' (old: '$($s.version)', new: '$version'), treating as potentially breaking" } diff --git a/scripts/utils.ps1 b/scripts/utils.ps1 index f1a1752..d74a5da 100644 --- a/scripts/utils.ps1 +++ b/scripts/utils.ps1 @@ -285,6 +285,100 @@ function Format-FileSize { } } +function Get-VersionChangeType { + <# + .SYNOPSIS + Analyzes version changes using semantic versioning to determine the type of update and appropriate emoji. + + .DESCRIPTION + Parses old and new version strings, compares them using semantic versioning rules, + and returns information about the change type, emoji indicator, and whether it's a major update. + + .PARAMETER OldVersion + The previous version string (e.g., "1.2.3" or "2.52.0.windows.1"). + + .PARAMETER NewVersion + The new version string (e.g., "1.3.0" or "3.0.0.windows.1"). + + .OUTPUTS + Returns a hashtable with the following keys: + - ChangeType: "major", "minor", "patch", "downgrade", or "unknown" + - Emoji: The corresponding emoji indicator (🔥, 🚀, ⬆️, or 🔄) + - IsMajor: Boolean indicating if this is a major version update + + .EXAMPLE + $result = Get-VersionChangeType -OldVersion "1.2.3" -NewVersion "2.0.0" + # Returns: @{ ChangeType = "major"; Emoji = "🔥"; IsMajor = $true } + + .EXAMPLE + $result = Get-VersionChangeType -OldVersion "1.2.3" -NewVersion "1.3.0" + # Returns: @{ ChangeType = "minor"; Emoji = "🚀"; IsMajor = $false } + #> + param( + [Parameter(Mandatory = $true)] + [string]$OldVersion, + + [Parameter(Mandatory = $true)] + [string]$NewVersion + ) + + $changeType = "unknown" + $emoji = "🔄" + $isMajor = $false + + try { + # Handle versions with more than 4 parts and strip pre-release identifiers + $oldVerStr = $OldVersion.Split('-')[0] + $newVerStr = $NewVersion.Split('-')[0] + + # Split by dots and take only numeric parts, first 4 max + $oldParts = $oldVerStr.Split('.') | Where-Object { $_ -match '^\d+$' } | Select-Object -First 4 + $newParts = $newVerStr.Split('.') | Where-Object { $_ -match '^\d+$' } | Select-Object -First 4 + + # Ensure we have at least 2 parts (major.minor) for semantic versioning + if ($oldParts.Count -ge 2 -and $newParts.Count -ge 2) { + $oldVerParseable = $oldParts -join '.' + $newVerParseable = $newParts -join '.' + + $oldVer = [System.Version]::Parse($oldVerParseable) + $newVer = [System.Version]::Parse($newVerParseable) + + if ($newVer -lt $oldVer) { + $changeType = "downgrade" + # Don't set emoji for downgrades in this function - caller handles it + } elseif ($newVer.Major -gt $oldVer.Major) { + $changeType = "major" + $emoji = "🔥" + $isMajor = $true + } elseif ($newVer.Minor -gt $oldVer.Minor) { + $changeType = "minor" + $emoji = "🚀" + } elseif ($newVer -gt $oldVer) { + $changeType = "patch" + $emoji = "⬆️" + } else { + # No version increase detected (versions are equal) + $changeType = "unknown" + $emoji = "🔄" + } + } else { + # Not enough numeric parts for semantic versioning + throw "Not enough numeric version parts" + } + } catch { + # If semantic versioning fails, return unknown + $changeType = "unknown" + $emoji = "🔄" + $isMajor = $false + } + + return @{ + ChangeType = $changeType + Emoji = $emoji + IsMajor = $isMajor + } +} + function Get-ArtifactDownloadUrl { <# .SYNOPSIS