Functions/Public/Merge-GitHubPullRequest.ps1
function Merge-GitHubPullRequest { <# .SYNOPSIS This cmdlet merges a pull request #> [CmdletBinding()] param( # The owner of the target repository [Parameter(ValueFromPipelineByPropertyName)] [string] $Owner = (Get-GitHubUser -Token $Token).login, # This doesn't work for org repos. # The name of the target repository [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [ValidateNotNullOrEmpty()] [ValidatePattern('^[\w-]+$')] [Alias('Repository')] [string] $RepositoryName, # Number of the pull request [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [int] $Number, # SHA that pull request head must match to allow merge. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Sha, [AllowEmptyString()] [string] $CommitTitle, # If you want to keep it empty, pass "`n" [AllowEmptyString()] [string] $CommitBody, # The merge method to use. # Defaults to whatever is allowed in the repo, in the order merge, squash, rebase. [ValidateSet('merge', 'squash', 'rebase')] [string] $MergeMethod, # If given, poll the commits status and wait with merging until they pass. # Progress is reported through Write-Progress. [switch] $WaitForStatusChecks, # If given, delete the branch and after merging. [switch] $DeleteBranch, [Security.SecureString] $Token ) process { $apiBody = @{ sha = $Sha } if ($CommitTitle) { $apiBody.commit_title = $CommitTitle } if ($CommitBody) { $apiBody.commit_body = $CommitBody } if ($MergeMethod) { $apiBody.merge_method = $MergeMethod } else { $repo = Get-GitHubRepository -Owner $Owner -RepositoryName $RepositoryName -Token $Token $apiBody.merge_method = if ($repo.allow_merge_commit) { 'merge' } elseif ($repo.allow_squash_merge) { 'squash' } elseif ($repo.allow_rebase_merge) { 'rebase' } } if ($WaitForStatusChecks) { while ($true) { $status = Get-GitHubCombinedCommitStatus -Owner $Owner -RepositoryName $RepositoryName -Ref $Sha -Token $Token $success = ($status.Statuses | Where-Object { $_.state -eq 'success' } | Measure-Object).Count $total = $status.TotalCount Write-Verbose "Commit status: $($status.state)" $updates = ($status.Statuses | ForEach-Object { $icon = switch ($_.State) { 'success' { "✅" } 'pending' { "🔄" } 'failure' { "❌" } 'error' { "❗️" } } "$icon $($_.Context) $($_.Description)" }) -join ", " if ($status.state -ne 'pending') { [Console]::Beep() if ($status.state -ne 'success') { Write-Error -Message "Status check $($status.state): $updates" return } break } if ($ProgressPreference -ne 'SilentlyContinue' -and $total -ne 0) { Write-Progress ` -Activity 'Waiting for status checks to pass' ` -Status "$success/$($total): $updates" ` -PercentComplete (($success / $total) * 100) } Start-Sleep -Seconds 10 } } $res = Invoke-GithubApi "repos/$Owner/$RepositoryName/pulls/$Number/merge" -Method PUT -Body ($apiBody | ConvertTo-Json) -Token $Token $res # Only delete the branch if merge was successful if ($res -and $res.merged -and $DeleteBranch) { Get-GitHubPullRequest -Owner $Owner -RepositoryName $RepositoryName -Number $Number -Token $Token | Remove-GitHubGitRef -Token $Token } } } |