Private/Invoke-GitHubApi.ps1
|
# Copyright (c) 2026 Jeffrey Snover. All rights reserved. # Licensed under the MIT License. See LICENSE file in the project root. function Invoke-GitHubApi { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Endpoint, [Parameter()] [ValidateSet('GET', 'POST', 'PATCH', 'PUT', 'DELETE')] [string]$Method = 'GET', [Parameter()] [object]$Body, [Parameter()] [string]$CallerName = 'Invoke-GitHubApi' ) Set-StrictMode -Version Latest $Token = $env:GITHUB_TOKEN if (-not $Token) { throw (New-ActionableError ` -Goal 'Call GitHub API' ` -Problem 'GITHUB_TOKEN environment variable is not set' ` -Location $CallerName ` -NextSteps @('Set $env:GITHUB_TOKEN to a GitHub personal access token', 'Token needs repo scope for data operations')) } $Headers = @{ Authorization = "Bearer $Token" Accept = 'application/vnd.github+json' 'User-Agent' = 'AITriad-DataRollback/1.0' } $Params = @{ Uri = "https://api.github.com$Endpoint" Method = $Method Headers = $Headers ErrorAction = 'Stop' } if ($Body) { $Params['Body'] = ($Body | ConvertTo-Json -Depth 10 -Compress) $Params['ContentType'] = 'application/json' } try { Invoke-RestMethod @Params } catch { $StatusCode = $null if ($_.Exception.PSObject.Properties['Response'] -and $_.Exception.Response) { $StatusCode = [int]$_.Exception.Response.StatusCode } $Msg = if ($StatusCode -eq 404) { 'Resource not found' } elseif ($StatusCode -eq 409) { 'Conflict — the operation could not be completed' } elseif ($StatusCode -eq 422) { 'Validation failed — check parameters' } elseif ($StatusCode) { "HTTP $StatusCode" } else { $_.Exception.Message } throw (New-ActionableError ` -Goal "$Method $Endpoint" ` -Problem "GitHub API error: $Msg" ` -Location $CallerName ` -NextSteps @('Verify GITHUB_TOKEN has repo scope', "Endpoint: $Endpoint")) } } |