Public/Test-CCCollaboration.ps1
|
function Test-CCCollaboration { <# .SYNOPSIS Validates collaboration health (stale branches, open PRs). .PARAMETER Repository GitHub repository in format "owner/repo". Auto-detected if not specified. .PARAMETER Token GitHub token. Falls back to GITHUB_TOKEN, GH_TOKEN, or gh CLI. .PARAMETER Standard Standard tier: core, active, minimal. Default: core. .PARAMETER Config Path to per-repo config file for overrides. .OUTPUTS [PSCustomObject[]] Array of check results. .EXAMPLE Test-CCCollaboration -Repository 'The-Code-Kitchen/LeadForge' #> [CmdletBinding()] [OutputType([PSCustomObject[]])] param( [Parameter()] [string]$Repository, [Parameter()] [string]$Token, [Parameter()] [ValidateSet('core', 'active', 'minimal')] [string]$Standard = 'core', [Parameter()] [string]$Config ) $results = [System.Collections.ArrayList]::new() $token = Resolve-CCToken -Token $Token if (-not $token) { throw "No GitHub token available. Set GITHUB_TOKEN or run 'gh auth login'." } $repo = Resolve-CCRepository -Repository $Repository if (-not $repo) { throw "Cannot determine repository. Specify -Repository 'owner/repo'." } $stdConfig = (Get-CCStandardConfig -Standard $Standard -ConfigPath $Config).collaboration # GH-COL-002: Stale branches if ($stdConfig.max_stale_branch_days) { $branches = @() $page = 1 do { $batch = Invoke-CCGitHubApi -Endpoint "repos/$repo/branches?per_page=100&page=$page" -Token $token if (-not $batch -or $batch.Count -eq 0) { break } $branches += $batch $page++ } while ($batch.Count -eq 100 -and $page -le 3) $repoInfo = Invoke-CCGitHubApi -Endpoint "repos/$repo" -Token $token $defaultBranch = $repoInfo.default_branch $cutoffDate = (Get-Date).AddDays(-$stdConfig.max_stale_branch_days) $staleBranches = @() foreach ($branch in $branches) { if ($branch.name -eq $defaultBranch) { continue } # Get commit date for this branch $commitInfo = Invoke-CCGitHubApi -Endpoint "repos/$repo/commits/$($branch.commit.sha)" -Token $token -AllowNotFound if ($commitInfo -and $commitInfo.commit.committer.date) { $commitDate = [DateTime]$commitInfo.commit.committer.date if ($commitDate -lt $cutoffDate) { $staleBranches += $branch.name } } } if ($staleBranches.Count -eq 0) { [void]$results.Add((New-CCCheckResult -CheckId 'GH-COL-002' -Category 'Collaboration' -Item 'Stale Branches' ` -Status 'Pass' -Severity 'Info' ` -Message "No stale branches (>$($stdConfig.max_stale_branch_days) days)")) } else { $preview = ($staleBranches | Select-Object -First 5) -join ', ' $more = if ($staleBranches.Count -gt 5) { " (+$($staleBranches.Count - 5) more)" } else { '' } [void]$results.Add((New-CCCheckResult -CheckId 'GH-COL-002' -Category 'Collaboration' -Item 'Stale Branches' ` -Status 'Warning' -Severity 'Warning' ` -Message "$($staleBranches.Count) stale branch(es): $preview$more" ` -Current $staleBranches.Count -Expected 0)) } } # GH-COL-003: Open PRs threshold if ($stdConfig.max_open_prs) { $openPRs = Invoke-CCGitHubApi -Endpoint "repos/$repo/pulls?state=open&per_page=100" -Token $token $openCount = if ($openPRs) { $openPRs.Count } else { 0 } if ($openCount -le $stdConfig.max_open_prs) { [void]$results.Add((New-CCCheckResult -CheckId 'GH-COL-003' -Category 'Collaboration' -Item 'Open PRs' ` -Status 'Pass' -Severity 'Info' ` -Message "$openCount open PR(s) (threshold: $($stdConfig.max_open_prs))")) } else { [void]$results.Add((New-CCCheckResult -CheckId 'GH-COL-003' -Category 'Collaboration' -Item 'Open PRs' ` -Status 'Warning' -Severity 'Warning' ` -Message "$openCount open PRs exceeds threshold of $($stdConfig.max_open_prs)" ` -Current $openCount -Expected $stdConfig.max_open_prs)) } } return $results.ToArray() } |