Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 8, 2025

Vendor CI/CD Workflow Improvements - Complete ✅

Summary of Changes

This PR enhances the vendor update CI/CD workflow with improved messaging, semantic versioning analysis, and automatic merging capabilities.

Completed Tasks

  • Analyze current workflow structure and update.ps1 script
  • Improve pluralization in PR title and messages (singular vs plural)
    • Single dependency: Shows dependency name and version instead of "1 dependency updated"
    • Multiple dependencies: Shows count with proper pluralization
  • Add proper emojis to workflow messages for better clarity
    • 🔥 for major version changes (breaking)
    • 🚀 for minor version changes
    • ⬆️ for patch version changes
    • 🔄 for unknown change types
    • 📦 for dependencies (single emoji only)
  • Implement semantic version analysis to detect breaking changes
    • Parses version strings (major.minor.patch)
    • Handles complex versions like "2.52.0.windows.1"
    • Filters non-numeric parts from version strings
  • Add logic to automatically push minor updates to master without PR
    • Directly commits and pushes to master for non-breaking changes
    • Skips PR creation to avoid bothering maintainers for safe updates
  • Add fallback to PR creation if auto-merge fails or breaking changes detected
    • Creates PR for major version updates (potential breaking changes)
    • Falls back to PR if direct push fails
  • Update workflow to warn in logs if unable to auto-merge
    • Clear error messages in step summary
    • Explains why manual review is required
  • Fix YAML linting issues (trailing spaces)
  • Improve version parsing to handle complex version strings
  • Test version parsing logic (6/6 tests passing)
  • Address code review feedback
    • Removed "Change Type" column from table
    • Added collapsible changelog section for major updates with links
    • Use single emoji only (removed double emoji)
    • Show dependency name and version for single updates
    • Updated emojis to improved visual indicators
    • Made new version bold in dependency table
    • Removed unused $headBeforeReset variable
    • Wrapped dependency count in backticks for consistency
  • Fix CI failure with proper variable initialization and error handling
  • Fix CodeQL workflow using PowerShell here-string (reverted previous echo/Write-Output attempts)
  • Run security checks (0 vulnerabilities found)

Key Features

  1. Smart Version Detection: Automatically detects breaking changes using semantic versioning
  2. Auto-merge for Safe Updates: Minor/patch updates are automatically merged to master
  3. Better User Experience: Clear, emoji-enhanced messages throughout the workflow with intuitive visual indicators (🔥 for major, 🚀 for minor, ⬆️ for patch)
  4. Single Dependency Messages: When updating one dependency, shows its name and version (e.g., "Updated git-for-windows from 2.52.0 to 2.53.0")
  5. Collapsible Changelog: Major updates include a <details> section with changelog and release notes links
  6. Robust Error Handling: Proper variable initialization with warning logging for edge cases
  7. Proper Pluralization: Context-aware messages for single vs. multiple dependencies
  8. Clear Visual Hierarchy: New versions displayed in bold for easy identification, dependency counts wrapped in backticks
  9. Clean Code: Removed unused variables and improved code quality

Visual Examples

Updated dependency table with new emojis:

Updated dependency table

Security Summary

✅ No security vulnerabilities detected by CodeQL analysis.

Original prompt

Improve pluralization for the update vendor CI/CD task; if there is only 1 vendored dependency, name that (also before/after version) instead of the current phrase that reads Updates to 1 vendored dependencies.

Also, improve the generated messages, in addition to that, use proper emojis where needed. We can look at depandabot's features for inspiration for our own tooling.

Lastly, if all the updated vendored dependencies are only minor (or more insignificant) and don't introduce breaking changes, the CI/CD workflow task can attempt to directly merge without needing a manual PR approve to avoid bothering the developers/maintainers. If this was unable to do so, you can warn about the unability to automatically merge/approve the PR in the step logs. It is prefered not to generate a PR in this case and automatically just push to master. If not, it should not break the current workflow where manual approves result in merging the PR.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Dec 8, 2025
Copilot AI changed the title [WIP] Improve pluralization and messaging for vendor CI/CD updates Auto-merge non-breaking vendor updates with improved messaging Dec 8, 2025
Copilot AI requested a review from DRSDavidSoft December 8, 2025 21:01
@DRSDavidSoft
Copy link
Contributor

This comment was marked as resolved.

@DRSDavidSoft

This comment was marked as resolved.

@DRSDavidSoft DRSDavidSoft marked this pull request as ready for review December 15, 2025 03:06
Copilot AI review requested due to automatic review settings December 15, 2025 03:06
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances the vendor dependency update workflow with intelligent semantic versioning analysis, improved messaging with emojis, and automatic merging capabilities for non-breaking changes. The goal is to reduce manual intervention for safe updates while maintaining proper review processes for potentially breaking changes.

Key changes:

  • Added semantic version parsing to detect major/minor/patch updates across both PowerShell script and GitHub Actions workflow
  • Implemented auto-merge feature that directly pushes minor/patch updates to master, bypassing PR creation for safe changes
  • Enhanced user-facing messages with context-aware formatting (single vs. multiple dependencies) and visual emoji indicators (🔥 for major, 🚀 for minor, ⬆️ for patch)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 16 comments.

File Description
scripts/update.ps1 Adds semantic version analysis logic, exports breaking change flags and update details to GitHub Actions environment
.github/workflows/vendor.yml Implements auto-merge workflow step, improves PR title/body formatting with conditional logic for single vs. multiple dependencies, adds collapsible changelog sections for major updates

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +186 to +203
- name: Auto-merge minor updates
if: env.COUNT_UPDATED > 0 && env.HAS_BREAKING_CHANGES != 'True'
shell: pwsh
run: |
try {
echo "### 🚀 Auto-merging Updates" >> $env:GITHUB_STEP_SUMMARY
echo "" >> $env:GITHUB_STEP_SUMMARY
echo "Attempting to automatically merge non-breaking changes to master..." >> $env:GITHUB_STEP_SUMMARY
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
# Commit the changes
git add vendor/sources.json
$commitResult = git commit -m "⬆️ Update dependencies ($env:LIST_UPDATED)"
# Push directly to master
git push origin HEAD:master
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The auto-merge feature directly pushes to the master branch without any approval or security checks. This could be a security risk if a malicious dependency update is introduced. Consider adding validation steps before auto-merging, such as running tests or security scans, even for minor/patch updates.

Copilot uses AI. Check for mistakes.
# If semantic versioning fails, treat as unknown (potentially breaking)
$changeType = "unknown"
$hasBreakingChanges = $true
Write-Verbose "Could not parse version as semantic version, treating as potentially breaking"
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

When version parsing fails and falls into the catch block, the code sets $hasBreakingChanges = $true as a safety measure. However, this means that any dependency with a non-standard version format will always require manual review, even if it's actually a safe patch update. Consider logging which specific dependency failed to parse to help with debugging and potential future improvements to the version parsing logic.

Suggested change
Write-Verbose "Could not parse version as semantic version, treating as potentially breaking"
Write-Verbose "Could not parse version as semantic version for dependency '$($s.name)' (old: '$($s.version)', new: '$version'), treating as potentially breaking"

Copilot uses AI. Check for mistakes.
Comment on lines +186 to +203
- name: Auto-merge minor updates
if: env.COUNT_UPDATED > 0 && env.HAS_BREAKING_CHANGES != 'True'
shell: pwsh
run: |
try {
echo "### 🚀 Auto-merging Updates" >> $env:GITHUB_STEP_SUMMARY
echo "" >> $env:GITHUB_STEP_SUMMARY
echo "Attempting to automatically merge non-breaking changes to master..." >> $env:GITHUB_STEP_SUMMARY
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
# Commit the changes
git add vendor/sources.json
$commitResult = git commit -m "⬆️ Update dependencies ($env:LIST_UPDATED)"
# Push directly to master
git push origin HEAD:master
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

There's a potential race condition if multiple workflow runs execute concurrently. If two workflows try to push to master at the same time, one will fail. While this is handled by the error catch block, it would be better to use a concurrency group to prevent multiple instances of this workflow from running simultaneously on the same branch.

Copilot uses AI. Check for mistakes.
Comment on lines +202 to +211
# Push directly to master
git push origin HEAD:master
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
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The $commitResult variable captures the output of git commit, but it's only used in a check on line 224. However, if the commit fails (e.g., no changes to commit), the script will proceed to try to push, which could fail. Consider checking if the commit succeeded before attempting to push, or use -ErrorAction Stop to halt on errors.

Suggested change
# Push directly to master
git push origin HEAD:master
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
if ($commitResult) {
# Push directly to master
git push origin HEAD:master
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
}

Copilot uses AI. Check for mistakes.
if: env.COUNT_UPDATED > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false')
with:
title: 'Updates to `${{ env.COUNT_UPDATED }}` vendored dependencies'
title: ${{ env.COUNT_UPDATED == '1' && format('⬆️ Update {0}', env.LIST_UPDATED) || format('⬆️ Update {0} vendored dependencies', env.COUNT_UPDATED) }}
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The expression env.COUNT_UPDATED == '1' in the format() function will not work as expected in GitHub Actions workflow expressions. In the context of workflow expressions (inside ${{ }}), you should use a simple comparison without env. prefix when comparing against string literals. The correct syntax should be: env.COUNT_UPDATED == 1 or use string comparison with quotes around the number.

Copilot uses AI. Check for mistakes.
Comment on lines +327 to +333
if ($newVer.Major -gt $oldVer.Major) {
$changeType = "major"
$hasBreakingChanges = $true
} elseif ($newVer.Minor -gt $oldVer.Minor) {
$changeType = "minor"
} else {
$changeType = "patch"
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The version comparison logic only checks if the major or minor version increased, but doesn't handle the case where the major/minor versions are equal and only the patch version changed. When both major and minor are equal but the patch increased, the code will incorrectly classify it as "patch" due to the else clause. However, if the patch version actually decreased (a downgrade), it would still be classified as "patch" rather than flagged as potentially problematic.

Suggested change
if ($newVer.Major -gt $oldVer.Major) {
$changeType = "major"
$hasBreakingChanges = $true
} elseif ($newVer.Minor -gt $oldVer.Minor) {
$changeType = "minor"
} else {
$changeType = "patch"
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"

Copilot uses AI. Check for mistakes.
Write-Warning "Failed to auto-merge: $($_.Exception.Message)"
# Reset only if a commit was made (check if HEAD moved)
$headBeforeReset = git rev-parse HEAD
Copy link

Copilot AI Dec 15, 2025

Choose a reason for hiding this comment

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

The variable $headBeforeReset is set but never used. It appears to be intended for checking whether to reset the commit, but the logic doesn't actually use this variable. Consider removing it or implementing the intended logic to check if HEAD actually moved before attempting a reset.

Suggested change
$headBeforeReset = git rev-parse HEAD

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot Either implement the missing logic, or remove it. Where was this added, any why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed in commit 10a0675. The variable was added in commit e64c0b1 as part of error handling logic with the intention to check if HEAD moved before resetting. However, it was never actually used - the code only checked $commitResult instead. Since the variable served no purpose, I removed it and simplified the comment to better reflect what the code actually does.

@DRSDavidSoft

This comment was marked as resolved.

@DRSDavidSoft DRSDavidSoft added the 🔄️ GitHub Actions Pull requests that update GitHub Actions code label Dec 15, 2025

This comment was marked as resolved.

This comment was marked as resolved.

if: env.COUNT_UPDATED > 0 && (env.HAS_BREAKING_CHANGES == 'True' || env.AUTO_MERGED == 'false')
with:
title: 'Updates to `${{ env.COUNT_UPDATED }}` vendored dependencies'
title: ${{ env.COUNT_UPDATED == '1' && format('⬆️ Update {0}', env.LIST_UPDATED) || format('⬆️ Update {0} vendored dependencies', env.COUNT_UPDATED) }}
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot The number of update should be wrapped in (`) like before

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 7b86263. The dependency count is now wrapped in backticks for the plural case to match the original format: 📦 Automatically updated {0} dependencies

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔄️ GitHub Actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants