66 # At 13:37 UTC every day.
77 - cron : ' 37 13 * * *'
88
9+ concurrency :
10+ group : vendor-update
11+ cancel-in-progress : false
12+
913defaults :
1014 run :
1115 shell : pwsh
@@ -45,64 +49,226 @@ jobs:
4549 env :
4650 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
4751 run : |
48- $currentVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json)
49- . .\scripts\update.ps1 -verbose
50- Set-GHVariable -Name COUNT_UPDATED -Value $count
51- $newVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json)
52- $listUpdated = ""
53- $updateMessage = "| Name | Old Version | New Version |`n| :--- | ---- | ---- |`n"
54- foreach ($s in $newVersion) {
55- $oldVersion = ($currentVersion | Where-Object {$_.name -eq $s.name}).version
56- if ($s.version -ne $oldVersion) {
57- $repoUrl = ($repoUrl = $s.Url.Replace("/archive/", "/releases/")).Substring(0, $repoUrl.IndexOf("/releases/")) + "/releases"
58- $listUpdated += "$($s.name) v$($s.version), "
59- $updateMessage += "| **[$($s.name)]($repoUrl)** | $oldVersion | **$($s.version)** |`n"
52+ $currentVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json)
53+ . .\scripts\update.ps1 -verbose
54+
55+ # Export count of updated packages (update.ps1 is expected to set $count)
56+ if (-not ($count)) { $count = 0 }
57+ Set-GHVariable -Name COUNT_UPDATED -Value $count
58+
59+ $newVersion = (Get-Content -Raw .\vendor\sources.json | ConvertFrom-Json)
60+ # Source utility functions
61+ . scripts/utils.ps1
62+
63+ $listUpdated = ""
64+ $updateMessage = "| Name | Old Version | New Version |`n| :--- | :---: | :---: |`n"
65+ $majorUpdates = @()
66+ $singleDepName = ""
67+ $singleDepOldVersion = ""
68+ $singleDepNewVersion = ""
69+ foreach ($s in $newVersion) {
70+ $oldVersion = ($currentVersion | Where-Object {$_.name -eq $s.name}).version
71+ if ($s.version -ne $oldVersion) {
72+ $repoUrl = ($repoUrl = $s.Url.Replace("/archive/", "/releases/")).Substring(0, $repoUrl.IndexOf("/releases/")) + "/releases"
73+
74+ # Store single dependency info for messages (only if this is the only update)
75+ if ($count -eq 1) {
76+ $singleDepName = $s.name
77+ $singleDepOldVersion = $oldVersion
78+ $singleDepNewVersion = $s.version
79+ }
80+
81+ # Determine change type and emoji using shared function
82+ $result = Get-VersionChangeType -OldVersion $oldVersion -NewVersion $s.version
83+ $changeType = $result.ChangeType
84+ $emoji = $result.Emoji
85+ $isMajor = $result.IsMajor
86+
87+ # Track major updates for changelog section
88+ if ($isMajor) {
89+ $compareUrl = "$repoUrl/compare/v$oldVersion...v$($s.version)"
90+ $majorUpdates += @{
91+ name = $s.name
92+ oldVersion = $oldVersion
93+ newVersion = $s.version
94+ compareUrl = $compareUrl
95+ repoUrl = $repoUrl
96+ }
97+ }
98+
99+ $listUpdated += "$($s.name) v$($s.version), "
100+ $updateMessage += "| $emoji **[$($s.name)]($repoUrl)** | \`$oldVersion\` | **\`$($s.version)\`** |`n"
101+ }
102+ }
103+
104+ if ($count -eq 0) { return }
105+
106+ Set-GHVariable -Name LIST_UPDATED -Value $listUpdated.Trim(', ')
107+ # Set single dependency variables (they will only be used if COUNT_UPDATED is 1)
108+ # Use safe fallback values in case variables weren't set (shouldn't happen but prevents errors)
109+ if ([string]::IsNullOrEmpty($singleDepName) -and $count -eq 1) {
110+ # This shouldn't happen, but if it does, log a warning
111+ Write-Warning "Single dependency name not set despite count being 1"
112+ $singleDepName = "unknown-package"
113+ $singleDepOldVersion = "unknown"
114+ $singleDepNewVersion = "unknown"
115+ } elseif ([string]::IsNullOrEmpty($singleDepName)) {
116+ # For multiple dependencies, set placeholder values (won't be used)
117+ $singleDepName = ""
118+ $singleDepOldVersion = ""
119+ $singleDepNewVersion = ""
60120 }
61- }
62- if ($count -eq 0) { return }
63- Set-GHVariable -Name LIST_UPDATED -Value $listUpdated.Trim(', ')
64121
65- echo "UPDATE_MESSAGE<<EOF`n$updateMessage`nEOF" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
122+ Set-GHVariable -Name SINGLE_DEP_NAME -Value $singleDepName
123+ Set-GHVariable -Name SINGLE_DEP_OLD_VERSION -Value $singleDepOldVersion
124+ Set-GHVariable -Name SINGLE_DEP_NEW_VERSION -Value $singleDepNewVersion
125+
126+ # Write multiline UPDATE_MESSAGE to GITHUB_ENV
127+ ## echo "UPDATE_MESSAGE<<EOF`n$updateMessage`nEOF" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
128+ Add-Content -Path $env:GITHUB_ENV -Value "UPDATE_MESSAGE<<EOF"
129+ Add-Content -Path $env:GITHUB_ENV -Value $updateMessage
130+ Add-Content -Path $env:GITHUB_ENV -Value "EOF"
131+
132+ # Generate major updates changelog section and export
133+ if ($majorUpdates.Count -gt 0) {
134+ $changelogSection = "`n<details>`n<summary>🔥 Major version updates - View changelog</summary>`n`n"
135+ foreach ($update in $majorUpdates) {
136+ $changelogSection += "### [$($update.name)]($($update.repoUrl))`n"
137+ $changelogSection += "**$($update.oldVersion)** → **$($update.newVersion)**`n`n"
138+ $changelogSection += "- [View full changelog]($($update.compareUrl))`n"
139+ $changelogSection += "- [Release notes]($($update.repoUrl)/tag/v$($update.newVersion))`n`n"
140+ }
141+ $changelogSection += "</details>`n"
142+
143+ Add-Content -Path $env:GITHUB_ENV -Value "CHANGELOG_SECTION<<EOF"
144+ Add-Content -Path $env:GITHUB_ENV -Value $changelogSection
145+ Add-Content -Path $env:GITHUB_ENV -Value "EOF"
146+ Add-Content -Path $env:GITHUB_ENV -Value "HAS_BREAKING_CHANGES=True"
147+ } else {
148+ Add-Content -Path $env:GITHUB_ENV -Value "CHANGELOG_SECTION="
149+ Add-Content -Path $env:GITHUB_ENV -Value "HAS_BREAKING_CHANGES=False"
150+ }
66151
67152 - name : Summary - Update check results
68153 shell : pwsh
69154 run : |
70155 $count = [int]$env:COUNT_UPDATED
156+
71157 if ($count -eq 0) {
72158 $summary = @"
73159 ### ✅ No Updates Available
74160
75- All vendor dependencies are up to date.
161+ All vendor dependencies are up to date! 🎉
76162 "@
77163 } else {
78164 $word = if ($count -eq 1) { 'dependency' } else { 'dependencies' }
79165 $summary = @"
80166 ### 🔄 Updates Found
81167
82- **$count** vendor $word updated:
168+ "@
169+ if ($count -eq 1) {
170+ $summary += '📦 **' + $env:SINGLE_DEP_NAME + '** updated from `' + $env:SINGLE_DEP_OLD_VERSION + '` to `' + $env:SINGLE_DEP_NEW_VERSION + '`' + "`n" + "`n"
171+ } else {
172+ $summary += '📦 **' + $count + '** vendor ' + $word + ' updated:' + "`n" + "`n"
173+ }
174+ }
83175
84- $env:UPDATE_MESSAGE
176+ $summary += $env:UPDATE_MESSAGE + "`n"
85177
86- "@
178+ # Check if we can auto-merge (only minor/patch changes)
179+ $hasBreaking = $env:HAS_BREAKING_CHANGES -eq 'True'
180+ if ($hasBreaking) {
181+ $summary += '> ⚠️ **Note:** This update contains major version changes that may include breaking changes.'
182+ } else {
183+ $summary += '> ℹ️ **Note:** This update only contains minor or patch changes.'
87184 }
88185
89186 $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
90187
188+ - name : Auto-merge minor updates
189+ if : env.COUNT_UPDATED > 0 && env.HAS_BREAKING_CHANGES != 'True'
190+ shell : pwsh
191+ run : |
192+ try {
193+ echo "### 🚀 Auto-merging Updates" >> $env:GITHUB_STEP_SUMMARY
194+ echo "" >> $env:GITHUB_STEP_SUMMARY
195+ echo "Attempting to automatically merge non-breaking changes to master..." >> $env:GITHUB_STEP_SUMMARY
196+
197+ git config --global user.name "github-actions[bot]"
198+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
199+
200+ # Commit the changes
201+ git add vendor/sources.json
202+ $commitResult = git commit -m "⬆️ Update dependencies ($env:LIST_UPDATED)"
203+ $commitSuccess = $LASTEXITCODE -eq 0
204+
205+ if ($commitSuccess) {
206+ # Push directly to master
207+ git push origin HEAD:master
208+ $pushSuccess = $LASTEXITCODE -eq 0
209+
210+ if ($pushSuccess) {
211+ echo "" >> $env:GITHUB_STEP_SUMMARY
212+ echo "✅ **Success!** Updates have been automatically merged to master." >> $env:GITHUB_STEP_SUMMARY
213+ echo "" >> $env:GITHUB_STEP_SUMMARY
214+ echo "**Updated dependencies:** $env:LIST_UPDATED" >> $env:GITHUB_STEP_SUMMARY
215+
216+ # Set a flag to skip PR creation
217+ echo "AUTO_MERGED=true" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
218+ } else {
219+ throw "Failed to push to master (exit code: $LASTEXITCODE)"
220+ }
221+ } else {
222+ throw "Failed to commit changes (exit code: $LASTEXITCODE)"
223+ }
224+ } catch {
225+ echo "" >> $env:GITHUB_STEP_SUMMARY
226+ echo "⚠️ **Warning:** Unable to automatically merge updates." >> $env:GITHUB_STEP_SUMMARY
227+ echo "" >> $env:GITHUB_STEP_SUMMARY
228+ echo "**Error:** $($_.Exception.Message)" >> $env:GITHUB_STEP_SUMMARY
229+ echo "" >> $env:GITHUB_STEP_SUMMARY
230+ echo "Falling back to creating a pull request..." >> $env:GITHUB_STEP_SUMMARY
231+
232+ Write-Warning "Failed to auto-merge: $($_.Exception.Message)"
233+
234+ # Only reset if commit was successful but push failed
235+ if ($commitSuccess -and -not $pushSuccess) {
236+ try {
237+ git reset --hard HEAD~1
238+ if ($LASTEXITCODE -ne 0) {
239+ Write-Warning "Failed to reset commit (exit code: $LASTEXITCODE), continuing with PR creation"
240+ }
241+ } catch {
242+ Write-Warning "Failed to reset commit: $($_.Exception.Message), continuing with PR creation"
243+ }
244+ }
245+
246+ # Set flag to create PR instead
247+ echo "AUTO_MERGED=false" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
248+ }
249+
91250 - uses : peter-evans/create-pull-request@v8
92- if : env.COUNT_UPDATED > 0
251+ if : fromJSON( env.COUNT_UPDATED) > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false')
93252 with :
94- title : ' Updates to ` ${{ env.COUNT_UPDATED }}` vendored dependencies'
253+ title : ${{ env.COUNT_UPDATED == 1 && format('⬆️ Update {0}', env.LIST_UPDATED) || format('⬆️ Update {0} vendored dependencies', env.COUNT_UPDATED) }}
95254 body : |
96- ### Automatically updated `${{ env.COUNT_UPDATED }}` dependencies:
255+ ### ${{ env.COUNT_UPDATED == 1 && format('📦 Updated {0} from `{1}` to `{2}`', env.SINGLE_DEP_NAME, env.SINGLE_DEP_OLD_VERSION, env.SINGLE_DEP_NEW_VERSION) || format('📦 Automatically updated `{0}` dependencies', env.COUNT_UPDATED) }}
256+
97257 ${{ env.UPDATE_MESSAGE }}
258+
259+ ${{ env.CHANGELOG_SECTION }}
260+
98261 ---
99- Please verify and then **Merge** the pull request to update.
262+
263+ ${{ env.HAS_BREAKING_CHANGES == 'True' && '⚠️ **This update contains major version changes that may include breaking changes.**' || 'ℹ️ This update only contains minor or patch changes.' }}
264+
265+ Please verify and then **Merge** the pull request to apply the updates.
100266 commit-message : ' ⬆️ Update dependencies (${{ env.LIST_UPDATED }})'
101267 branch : update-vendor
102268 base : master
103269
104270 - name : Summary - Pull request created
105- if : env.COUNT_UPDATED > 0
271+ if : env.COUNT_UPDATED > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false')
106272 shell : pwsh
107273 run : |
108274 $summary = @"
@@ -112,9 +278,19 @@ jobs:
112278
113279 **Branch:** ``update-vendor``
114280
115- **Updated dependencies:** $env:LIST_UPDATED
281+ $(if (-not [string]::IsNullOrEmpty($env:LIST_UPDATED)) { " **Updated dependencies:** $env:LIST_UPDATED" } else { "**Updated dependencies:** " })
116282
283+ "@
284+
285+ if ($env:HAS_BREAKING_CHANGES -eq 'True') {
286+ $summary += "> ⚠️ **Manual review required:** This update contains major version changes."
287+ } else {
288+ $summary += "> ℹ️ **Note:** Auto-merge failed, manual review required."
289+ }
290+
291+ $summary += @"
117292 > Please review and merge the pull request to apply the updates.
293+
118294 "@
119295
120296 $summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding utf8
0 commit comments