Get latest merged PRs with GitHub APIs
Summary
This sample uses the GitHub APIs to get the latest PRs merged in your Repository. Useful for repository maintainers and inspiration of other automate tasks you could perform with GitHub APIs.
Note:
- This may (if calls are throttled) require a PAT Token, the sample includes getting the token from a text file. This isnt the most secure way of storing and is beyond the scope of the sample. Check out this for a better way or use your own preferred way to store these: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.secretmanagement/?view=ps-modules
- Creating a GitHub token, but advise read only access, with minimal permissions: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token
Script Example Usage:
.\Get-GitHubPRsSince.ps1 -RepoOwner "<RepoOwner e.g. pnp>" -RepoName "<RepoName e.g. copilot-pro-dev-samples>" -NoOfWeeksSince 2
[CmdletBinding()]
param (
[string]$RepoOwner = "<RepoOwner e.g. pnp>",
[string]$RepoName = "<RepoName e.g. copilot-pro-dev-samples>",
[int]$NoOfWeeksSince = 2 # ISO 8601 format, e.g. "2025-07-01T00:00:00Z"
)
begin {
# ------------------------------------------------------------------------------
# Introduction
# ------------------------------------------------------------------------------
Write-Host " Welcome to GitHub PRs, this script will read latest PRs on a Repository" -ForegroundColor Green
# ------------------------------------------------------------------------------
# Read the Token file get the github token
$githubTokenFile = "github-token.txt"
$page = 1
$perPage = 100
# Calculate the date since which to fetch PRs
$sinceDate = (Get-Date).AddDays( - ($NoOfWeeksSince * 7)).ToString("yyyy-MM-ddTHH:mm:ssZ")
# Prepare CSV file name
$friendlyDate = $sinceDate -replace ":","-"
$csvFileName = "MergedPRs_$($RepoOwner)_$($RepoName)_Since$($friendlyDate).csv"
}
process {
if (Test-Path $githubTokenFile) {
$githubToken = Get-Content -Path $githubTokenFile -ErrorAction Stop
}
else {
Write-Error "GitHub token file not found: $githubTokenFile"
exit 1
}
$headers = @{
Authorization = "token $githubToken"
Accept = "application/vnd.github+json"
}
$allPRs = @()
do {
$url = "https://api.github.com/repos/$RepoOwner/$RepoName/pulls?state=closed&sort=merged_at&direction=desc&per_page=$perPage&page=$page"
$prs = Invoke-RestMethod -Uri $url -Headers $headers
foreach ($pr in $prs) {
if ($pr.merged_at -ge $sinceDate -and $pr.state -eq "closed") {
$allPRs += $pr
}
}
$page++
} while ($prs.Count -eq $perPage)
#--------------------------------------------------------------------------------------
# Produce Report of the latest merged PRs as Output PRs with user login and profile link
#--------------------------------------------------------------------------------------
if($allPRs.Count -eq 0) {
Write-Host "No PRs found that were merged in the last $NoOfWeeksSince weeks." -ForegroundColor Yellow
return
}else{
$formattedList = $allPRs | Select-Object `
@{Name = "ID"; Expression = { $_.number } },
@{Name = "PR Title"; Expression = { $_.title } },
@{Name = "User Login"; Expression = { $_.user.login } },
@{Name = "User Public Profile"; Expression = { $_.user.html_url } },
@{Name = "Merged"; Expression = { $_.merged_at } }
$formattedList | Format-Table -AutoSize
Write-Host "`nTotal PRs merged in the last $NoOfWeeksSince weeks: $($allPRs.Count)" -ForegroundColor Cyan
# Write to CSV file
$formattedList | Export-Csv -Path $csvFileName -NoTypeInformation -Encoding UTF8
Write-Host "Report saved to $csvFileName"
}
}
end {
Write-Host "Done! :)" -ForegroundColor Green
}
Check out the GitHub API Docs to learn more at: https://docs.github.com/en/rest/using-the-rest-api/getting-started-with-the-rest-api?apiVersion=2022-11-28
Contributors
Author(s) |
---|
Paul Bullock |
Disclaimer
THESE SAMPLES ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.