Public/New-PSUAiPoweredPullRequest.ps1
function New-PSUAiPoweredPullRequest { <# .SYNOPSIS Uses Gemini AI to generate a professional Pull Request (PR) title and description from Git change summaries. .DESCRIPTION This function takes Git change summaries and uses the Gemini model (via Invoke-PSUPromptOnGeminiAi) to produce a high-quality PR title and description written from a developer or DevOps perspective. .PARAMETER BaseBranch (Optional) The base branch to compare against. Default value is the default branch from git symbolic-ref refs/remotes/origin/HEAD. .PARAMETER FeatureBranch (Optional) The feature branch being merged. Default value is the current git branch from git branch --show-current. .PARAMETER PullRequestTemplate (Optional) Path to the Pull Request template file. Default value is "C:\Temp\PRTemplate.txt". .PARAMETER ApiKey (Optional) The API key for Google Gemini AI service. Default value is $env:API_KEY_GEMINI. Set using: Set-PSUUserEnvironmentVariable -Name "API_KEY_GEMINI" -Value "your-api-key" .PARAMETER CompleteOnApproval (Optional) Switch parameter to enable auto-completion when the pull request is approved. This will be passed to the underlying PR creation function. .OUTPUTS [PSCustomObject] .EXAMPLE New-PSUAiPoweredPullRequest .EXAMPLE New-PSUAiPoweredPullRequest -CompleteOnApproval Generates an AI-powered pull request that will automatically complete when approved. .NOTES Author: Lakshmanachari Panuganti Date: 28th July 2025 .LINK https://github.com/lakshmanachari-panuganti/OMG.PSUtilities/tree/main/OMG.PSUtilities.AI https://www.linkedin.com/in/lakshmanachari-panuganti/ https://www.powershellgallery.com/packages/OMG.PSUtilities.AI https://ai.google.dev/gemini-api/docs #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidUsingWriteHost', '', Justification = 'This is intended for this function to display formatted output to the user on the console' )] param ( [Parameter()] [string]$BaseBranch = $(git symbolic-ref refs/remotes/origin/HEAD | Split-Path -Leaf), [Parameter()] [string]$FeatureBranch = $(git branch --show-current), # Add validation for template path [Parameter()] [ValidateScript({ if ($_ -and -not (Test-Path $_)) { throw "PR template file not found: $_" } return $true })] [string]$PullRequestTemplate, [Parameter()] [string] $ApiKey = $env:API_KEY_GEMINI, [Parameter()] [switch]$CompleteOnApproval ) $UpdateChangeLog = Read-Host "Do you want me to update ChangeLog.md file with the changes? (Y/N)" if ($UpdateChangeLog -eq 'Y') { Update-PSUChangeLog } $ChangeSummary = Get-PSUAiPoweredGitChangeSummary -ApiKeyGemini $ApiKey if (-not $ChangeSummary) { Write-Warning "No changes found " return } # Convert summaries into a nice prompt for Gemini $formattedChanges = ($ChangeSummary | ForEach-Object { "- File: $($_.File) | Change: $($_.TypeOfChange) | Summary: $($_.Summary)" }) -join "`n" # Handle PR template - check if file exists $PRTemplateContent = "" $PRTemplateStatement = @() if (Test-Path $PullRequestTemplate) { try { $PRTemplateContent = Get-Content -Path $PullRequestTemplate -ErrorAction Stop | Out-String $PRTemplateStatement = @( "NOTE: Please follow the Pull Request template guidelines below carefully:", "", $PRTemplateContent, "", "DO NOT modify the template structure.", "DO NOT change the checklists or their wording.", "Update the checklists by marking the correct [X] where applicable.", "DO NOT alter anything that impacts organizational standards.", "ONLY update the DESCRIPTION section thoughtfully and clearly." ) } catch { Write-Warning "Could not read PR template file: $($_.Exception.Message)" } } else { Write-Verbose "No PR template specified. Proceeding without template." } $prompt = @" You are a professional software engineer and DevOps expert. Given the following Git change summaries, generate a high-quality Pull Request title and a detailed, clear description suitable for code review. Use a professional tone, and ensure the description is helpful to both developers, reviewers and should be in human writing style. ### Git Change Summaries: $formattedChanges Finally remove any duplicate data in description and respond in the following JSON format (***ONLY JSON format***): { "title": "<generated-title>", "description": "<generated-description>" } $PRTemplateStatement "@.Trim() # Call Gemini to generate PR content $response = Invoke-PSUPromptOnGeminiAi -Prompt $prompt -ReturnJsonResponse # Try parsing the AI response as JSON try { $parsed = $response | ConvertFrom-Json -ErrorAction Stop $PRContent = [PSCustomObject]@{ Title = $parsed.title Description = $parsed.description } ($parsed.title) + '`n ' + ($parsed.description) | Set-Clipboard Convert-PSUPullRequestSummaryToHtml -Title $parsed.title -Description $parsed.description -OpenInBrowser # Better user prompt with clearer options Write-Host 'Choose an option:' -ForegroundColor Yellow Write-Host ' Y - Submit the pull request now' -ForegroundColor Cyan Write-Host ' N - Cancel and exit' -ForegroundColor Cyan Write-Host ' R - Regenerate with new AI content' -ForegroundColor Cyan Write-Host ' D - Draft the PR' -ForegroundColor Cyan $readHost = Read-Host 'Enter your choice (Y/N/R/D)' -ForegroundColor Yellow switch ($readHost) { 'Y' { # Determining the gitProvider $remoteUrl = git remote get-url origin if ($remoteUrl -match 'github\.com') { Write-Host "Creating the GitHub pull request" $params = @{ Title = $PRContent.Title Description = $PRContent.Description Token = $env:GITHUB_TOKEN } if ($CompleteOnApproval) { $params.CompleteOnApproval = $true } New-PSUGithubPullRequest @params } elseif ($remoteUrl -match 'dev\.azure\.com|visualstudio\.com') { Write-Host "Creating the Azure DevOps pull request" $params = @{ Title = $PRContent.Title Description = $PRContent.Description PAT = $env:PAT } if ($CompleteOnApproval) { $params.CompleteOnApproval = $true } New-PSUADOPullRequest @params } else { Write-Warning "git url: $remoteUrl" Write-Warning "Automatic pull request creation is not supported for this Git provider. Please create the PR manually." } } 'N' { Write-Host "Pull request submission canceled." } 'R' { Write-Host "Regenerating PR content..." return (New-PSUAiPoweredPullRequest @PSBoundParameters) } 'D' { # Determining the $gitProvider for draft PR $remoteUrl = git remote get-url origin if ($remoteUrl -match 'github\.com') { Write-Host "Creating draft GitHub pull request" $params = @{ Title = $PRContent.Title Description = $PRContent.Description Token = $env:GITHUB_TOKEN Draft = $true } if ($CompleteOnApproval) { $params.CompleteOnApproval = $true } New-PSUGithubPullRequest @params } elseif ($remoteUrl -match 'dev\.azure\.com|visualstudio\.com') { Write-Host "Creating draft Azure DevOps pull request" $params = @{ Title = $PRContent.Title Description = $PRContent.Description PAT = $env:PAT Draft = $true } if ($CompleteOnApproval) { $params.CompleteOnApproval = $true } New-PSUADOPullRequest @params } else { Write-Warning "git url: $remoteUrl" Write-Warning "Automatic pull request creation is not supported for this Git provider. Please create the PR manually." } } default { Write-Warning "Invalid choice. Please enter Y, N, R, or D." } } } catch { $PSCmdlet.ThrowTerminatingError() } } |