Report

Get latest merged PRs with GitHub APIs

Get a report from the last 2 weeks, useful for maintainers who regularly have contributions and want to see a summary of recent activity.

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:

Script Example Usage:

powershell

.\Get-GitHubPRsSince.ps1 -RepoOwner "<RepoOwner e.g. pnp>" -RepoName "<RepoName e.g. copilot-pro-dev-samples>" -NoOfWeeksSince 2
powershell

[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=created&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
}

Contributors

Author(s)
Paul Bullock
Christian Veenhuis

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.

Tool documentation & references

Keep exploring