Public/Approve-PSUGithubPullRequest.ps1
function Approve-PSUGithubPullRequest { <# .SYNOPSIS Approves a pull request in GitHub using REST API. .DESCRIPTION This function creates a review approval for a pull request in GitHub by its number. It supports different review states including approval, request changes, or comments only. .PARAMETER Owner (Optional) The GitHub repository owner (username or organization). Default value is auto-detected from git remote origin URL. .PARAMETER Repository (Optional) The GitHub repository name. Default value is auto-detected from git remote origin URL. .PARAMETER PullRequestNumber (Mandatory) The number/ID of the pull request to approve. .PARAMETER ReviewState (Optional) The review state to submit: - 'APPROVE': Approve the pull request - 'REQUEST_CHANGES': Request changes before approval - 'COMMENT': Comment without explicit approval Default value is 'APPROVE'. .PARAMETER Comment (Optional) Comment to add with the review. .PARAMETER Token (Optional) GitHub Personal Access Token for authentication. Default value is $env:GITHUB_TOKEN. Set using: Set-PSUUserEnvironmentVariable -Name "GITHUB_TOKEN" -Value "value_of_token" .EXAMPLE Approve-PSUGithubPullRequest -PullRequestNumber 42 Approves pull request #42 using auto-detected repository. .EXAMPLE Approve-PSUGithubPullRequest -Owner "myuser" -Repository "myrepo" -PullRequestNumber 42 -Comment "LGTM! Great work." Approves pull request #42 with a comment. .EXAMPLE Approve-PSUGithubPullRequest -PullRequestNumber 42 -ReviewState "REQUEST_CHANGES" -Comment "Please fix the unit tests" Requests changes on pull request #42 with a comment. .OUTPUTS [PSCustomObject] .NOTES Author: Lakshmanachari Panuganti Date: 19th August 2025 Requires: GitHub Personal Access Token with repo permissions .LINK https://github.com/lakshmanachari-panuganti/OMG.PSUtilities/tree/main/OMG.PSUtilities.Core https://www.linkedin.com/in/lakshmanachari-panuganti/ https://www.powershellgallery.com/packages/OMG.PSUtilities.Core https://docs.github.com/en/rest/pulls/reviews#create-a-review-for-a-pull-request #> [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]$Owner, [Parameter()] [string]$Repository, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [int]$PullRequestNumber, [Parameter()] [ValidateSet('APPROVE', 'REQUEST_CHANGES', 'COMMENT')] [string]$ReviewState = 'APPROVE', [Parameter()] [string]$Comment, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Token = $env:GITHUB_TOKEN ) process { try { # Auto-detect repository info if not provided if (-not $Owner -or -not $Repository) { $remoteUrl = git remote get-url origin 2>$null if (-not $remoteUrl) { throw "No git remote origin found and Owner/Repository not specified." } if ($remoteUrl -match 'github\.com[/:]([^/]+)/([^/]+?)(?:\.git)?/?$') { if (-not $Owner) { $Owner = $matches[1] } if (-not $Repository) { $Repository = $matches[2] } } else { throw "Could not parse GitHub repository from remote URL: $remoteUrl. Please specify Owner and Repository parameters." } } # Validate token if (-not $Token) { throw "GitHub token not found. Set it using: Set-PSUUserEnvironmentVariable -Name 'GITHUB_TOKEN' -Value 'your-token'" } # Prepare headers $headers = @{ 'Authorization' = "Bearer $Token" 'Accept' = 'application/vnd.github.v3+json' 'X-GitHub-Api-Version' = '2022-11-28' } # Get PR details first to validate it exists $prUri = "https://api.github.com/repos/$Owner/$Repository/pulls/$PullRequestNumber" Write-Verbose "Getting pull request details from: $prUri" $prDetails = Invoke-RestMethod -Method Get -Uri $prUri -Headers $headers -ErrorAction Stop # Prepare review body $body = @{ event = $ReviewState } if ($Comment) { $body.body = $Comment } $bodyJson = $body | ConvertTo-Json -Depth 10 # Submit the review $reviewUri = "https://api.github.com/repos/$Owner/$Repository/pulls/$PullRequestNumber/reviews" Write-Verbose "Submitting review for pull request #$PullRequestNumber in repository: $Owner/$Repository" Write-Verbose "Review state: $ReviewState" Write-Verbose "API URI: $reviewUri" $response = Invoke-RestMethod -Method Post -Uri $reviewUri -Headers $headers -Body $bodyJson -ContentType "application/json" -ErrorAction Stop # Determine action text for display $actionText = switch ($ReviewState) { 'APPROVE' { 'approved' } 'REQUEST_CHANGES' { 'requested changes for' } 'COMMENT' { 'commented on' } default { 'reviewed' } } Write-Host "Successfully $actionText pull request #$PullRequestNumber" -ForegroundColor Green Write-Host "PR URL: $($prDetails.html_url)" -ForegroundColor Cyan Write-Host "Review URL: $($response.html_url)" -ForegroundColor Cyan if ($Comment) { Write-Host "Comment: $Comment" -ForegroundColor Yellow } # Return structured result [PSCustomObject]@{ PullRequestNumber = $PullRequestNumber ReviewId = $response.id ReviewState = $response.state ActionText = $actionText Comment = $Comment ReviewerLogin = $response.user.login SubmittedAt = $response.submitted_at Owner = $Owner Repository = $Repository PullRequestUrl = $prDetails.html_url ReviewUrl = $response.html_url PSTypeName = 'PSU.GitHub.PullRequestApproval' } } catch { $PSCmdlet.ThrowTerminatingError($_) } } } |