Public/Get-GitHubWorkflowRun.ps1
|
# Copyright (c) 2026 Jeffrey Snover. All rights reserved. # Licensed under the MIT License. See LICENSE file in the project root. function Get-GitHubWorkflowRun { <# .SYNOPSIS Fetches a GitHub Actions workflow run for a commit SHA (or by run ID), with per-job conclusions. .DESCRIPTION Consolidates the workflow-run status queries duplicated in `.github/workflows/deploy-azure.yml:86-99` (CI-readiness gate for a deploy — needs per-job status by name) and `.github/workflows/container.yml:45-46` (simpler top-level conclusion check before a container build). Both call the same GitHub API endpoints — this cmdlet is one entry point for both. Two lookup modes: - By SHA: -Repo + -Workflow + -CommitSha. Fetches the most recent run of the given workflow for that commit. - By ID: -Repo + -RunId. Fetches that specific run. Returns [GitHubWorkflowRunInfo] with RunId/Status/Conclusion/ Jobs (each with Name/Status/Conclusion). Jobs are only fetched when at least one job is present in the run. .PARAMETER Repo Owner/repo (e.g. 'jpsnover/ai-triad-research'). .PARAMETER Workflow Workflow file name (e.g. 'ci.yml'). Required when resolving by commit SHA; ignored when -RunId is provided. .PARAMETER CommitSha Head SHA to look up. Required unless -RunId is provided. .PARAMETER RunId Specific workflow run ID. Overrides -CommitSha/-Workflow lookup. .EXAMPLE Get-GitHubWorkflowRun -Repo 'jpsnover/ai-triad-research' -Workflow 'ci.yml' -CommitSha $sha .EXAMPLE (Get-GitHubWorkflowRun -Repo $r -Workflow ci.yml -CommitSha $sha).Jobs | Where-Object Name -eq 'test-container' .LINK Show-AITriadHelp .LINK Test-GitHubHealth #> [CmdletBinding(DefaultParameterSetName = 'BySha')] param( [Parameter(Mandatory)] [string]$Repo, [Parameter(Mandatory, ParameterSetName = 'BySha')] [string]$Workflow, [Parameter(Mandatory, ParameterSetName = 'BySha')] [string]$CommitSha, [Parameter(Mandatory, ParameterSetName = 'ById')] [long]$RunId ) Set-StrictMode -Version Latest # ── Resolve run ────────────────────────────────────────────────────── $Run = $null if ($PSCmdlet.ParameterSetName -eq 'BySha') { $Endpoint = "/repos/$Repo/actions/workflows/$Workflow/runs?head_sha=$CommitSha&per_page=1" $Response = Invoke-GitHubApi -Endpoint $Endpoint -Method 'GET' ` -CallerName 'Get-GitHubWorkflowRun' if ($Response -and $Response.PSObject.Properties['workflow_runs']) { $Runs = @($Response.workflow_runs) if ($Runs.Count -gt 0) { $Run = $Runs[0] } } } else { $Run = Invoke-GitHubApi -Endpoint "/repos/$Repo/actions/runs/$RunId" ` -Method 'GET' -CallerName 'Get-GitHubWorkflowRun' } if (-not $Run) { Write-Verbose 'No matching workflow run found' return $null } # ── Fetch jobs ─────────────────────────────────────────────────────── $Jobs = [System.Collections.Generic.List[object]]::new() try { $JobsResponse = Invoke-GitHubApi -Endpoint "/repos/$Repo/actions/runs/$($Run.id)/jobs" ` -Method 'GET' -CallerName 'Get-GitHubWorkflowRun' if ($JobsResponse -and $JobsResponse.PSObject.Properties['jobs']) { foreach ($j in @($JobsResponse.jobs)) { $JobInfo = [GitHubWorkflowJobInfo]::new() $JobInfo.Name = [string]$j.name if ($j.PSObject.Properties['status']) { $JobInfo.Status = [string]$j.status } if ($j.PSObject.Properties['conclusion']) { $JobInfo.Conclusion = [string]$j.conclusion } $Jobs.Add($JobInfo) } } } catch { Write-Warning "Failed to fetch jobs for run $($Run.id): $($_.Exception.Message)" } $Result = [GitHubWorkflowRunInfo]::new() $Result.RunId = [long]$Run.id if ($Run.PSObject.Properties['status']) { $Result.Status = [string]$Run.status } if ($Run.PSObject.Properties['conclusion']) { $Result.Conclusion = [string]$Run.conclusion } if ($Run.PSObject.Properties['head_sha']) { $Result.HeadSha = [string]$Run.head_sha } if ($Run.PSObject.Properties['html_url']) { $Result.Url = [string]$Run.html_url } $Result.Jobs = @($Jobs) $Result } |