|
| 1 | +[CmdletBinding()] |
| 2 | +param() |
| 3 | + |
| 4 | +$ErrorActionPreference = 'Stop' |
| 5 | + |
| 6 | +$repoRoot = (Resolve-Path (Join-Path $env:GITHUB_ACTION_PATH "../..")).Path |
| 7 | +$project = Join-Path $repoRoot "PowerForge.Cli/PowerForge.Cli.csproj" |
| 8 | + |
| 9 | +function Format-GiB { |
| 10 | + param([long] $Bytes) |
| 11 | + |
| 12 | + if ($Bytes -le 0) { |
| 13 | + return '0.0 GiB' |
| 14 | + } |
| 15 | + |
| 16 | + return ('{0:N1} GiB' -f ($Bytes / 1GB)) |
| 17 | +} |
| 18 | + |
| 19 | +function Write-MarkdownSummary { |
| 20 | + param([string[]] $Lines) |
| 21 | + |
| 22 | + if ([string]::IsNullOrWhiteSpace($env:GITHUB_STEP_SUMMARY)) { |
| 23 | + return |
| 24 | + } |
| 25 | + |
| 26 | + Add-Content -Path $env:GITHUB_STEP_SUMMARY -Value ($Lines -join [Environment]::NewLine) |
| 27 | +} |
| 28 | + |
| 29 | +function Resolve-ConfigPath { |
| 30 | + $configPath = $env:INPUT_CONFIG_PATH |
| 31 | + if ([string]::IsNullOrWhiteSpace($configPath)) { |
| 32 | + $configPath = '.powerforge/github-housekeeping.json' |
| 33 | + } |
| 34 | + |
| 35 | + if ([System.IO.Path]::IsPathRooted($configPath)) { |
| 36 | + return [System.IO.Path]::GetFullPath($configPath) |
| 37 | + } |
| 38 | + |
| 39 | + if ([string]::IsNullOrWhiteSpace($env:GITHUB_WORKSPACE)) { |
| 40 | + throw 'GITHUB_WORKSPACE is not set.' |
| 41 | + } |
| 42 | + |
| 43 | + return [System.IO.Path]::GetFullPath((Join-Path $env:GITHUB_WORKSPACE $configPath)) |
| 44 | +} |
| 45 | + |
| 46 | +function Write-HousekeepingSummary { |
| 47 | + param([pscustomobject] $Envelope) |
| 48 | + |
| 49 | + if (-not $Envelope.result) { |
| 50 | + return |
| 51 | + } |
| 52 | + |
| 53 | + $result = $Envelope.result |
| 54 | + $lines = @( |
| 55 | + "### GitHub housekeeping", |
| 56 | + "", |
| 57 | + "- Mode: $(if ($result.dryRun) { 'dry-run' } else { 'apply' })", |
| 58 | + "- Requested sections: $((@($result.requestedSections) -join ', '))", |
| 59 | + "- Completed sections: $((@($result.completedSections) -join ', '))", |
| 60 | + "- Failed sections: $((@($result.failedSections) -join ', '))", |
| 61 | + "- Success: $(if ($Envelope.success) { 'yes' } else { 'no' })" |
| 62 | + ) |
| 63 | + |
| 64 | + if ($result.message) { |
| 65 | + $lines += "- Message: $($result.message)" |
| 66 | + } |
| 67 | + |
| 68 | + if ($result.caches) { |
| 69 | + $lines += '' |
| 70 | + $lines += '#### Caches' |
| 71 | + if ($result.caches.usageBefore) { |
| 72 | + $lines += "- Usage before: $($result.caches.usageBefore.activeCachesCount) caches, $(Format-GiB ([long]$result.caches.usageBefore.activeCachesSizeInBytes))" |
| 73 | + } |
| 74 | + if ($result.caches.usageAfter) { |
| 75 | + $lines += "- Usage after: $($result.caches.usageAfter.activeCachesCount) caches, $(Format-GiB ([long]$result.caches.usageAfter.activeCachesSizeInBytes))" |
| 76 | + } |
| 77 | + $lines += "- Planned deletes: $($result.caches.plannedDeletes) ($(Format-GiB ([long]$result.caches.plannedDeleteBytes)))" |
| 78 | + $lines += "- Deleted: $($result.caches.deletedCaches) ($(Format-GiB ([long]$result.caches.deletedBytes)))" |
| 79 | + $lines += "- Failed deletes: $($result.caches.failedDeletes)" |
| 80 | + } |
| 81 | + |
| 82 | + if ($result.artifacts) { |
| 83 | + $lines += '' |
| 84 | + $lines += '#### Artifacts' |
| 85 | + $lines += "- Planned deletes: $($result.artifacts.plannedDeletes) ($(Format-GiB ([long]$result.artifacts.plannedDeleteBytes)))" |
| 86 | + $lines += "- Deleted: $($result.artifacts.deletedArtifacts) ($(Format-GiB ([long]$result.artifacts.deletedBytes)))" |
| 87 | + $lines += "- Failed deletes: $($result.artifacts.failedDeletes)" |
| 88 | + } |
| 89 | + |
| 90 | + if ($result.runner) { |
| 91 | + $lines += '' |
| 92 | + $lines += '#### Runner' |
| 93 | + $lines += "- Free before: $(Format-GiB ([long]$result.runner.freeBytesBefore))" |
| 94 | + $lines += "- Free after: $(Format-GiB ([long]$result.runner.freeBytesAfter))" |
| 95 | + $lines += "- Aggressive cleanup: $(if ($result.runner.aggressiveApplied) { 'yes' } else { 'no' })" |
| 96 | + } |
| 97 | + |
| 98 | + Write-Host ("GitHub housekeeping: requested={0}; completed={1}; failed={2}" -f ` |
| 99 | + (@($result.requestedSections) -join ','), ` |
| 100 | + (@($result.completedSections) -join ','), ` |
| 101 | + (@($result.failedSections) -join ',')) |
| 102 | + |
| 103 | + Write-MarkdownSummary -Lines ($lines + '') |
| 104 | +} |
| 105 | + |
| 106 | +$configPath = Resolve-ConfigPath |
| 107 | +if (-not (Test-Path -LiteralPath $configPath)) { |
| 108 | + throw "Housekeeping config not found: $configPath" |
| 109 | +} |
| 110 | + |
| 111 | +$arguments = [System.Collections.Generic.List[string]]::new() |
| 112 | +$arguments.AddRange(@( |
| 113 | + 'run', '--project', $project, '-c', 'Release', '--no-build', '--', |
| 114 | + 'github', 'housekeeping', |
| 115 | + '--config', $configPath |
| 116 | +)) |
| 117 | + |
| 118 | +if ($env:INPUT_APPLY -eq 'true') { |
| 119 | + $null = $arguments.Add('--apply') |
| 120 | +} else { |
| 121 | + $null = $arguments.Add('--dry-run') |
| 122 | +} |
| 123 | + |
| 124 | +if (-not [string]::IsNullOrWhiteSpace($env:POWERFORGE_GITHUB_TOKEN)) { |
| 125 | + $null = $arguments.Add('--token') |
| 126 | + $null = $arguments.Add($env:POWERFORGE_GITHUB_TOKEN) |
| 127 | +} |
| 128 | + |
| 129 | +$null = $arguments.Add('--output') |
| 130 | +$null = $arguments.Add('json') |
| 131 | + |
| 132 | +$rawOutput = (& dotnet $arguments 2>&1 | Out-String).Trim() |
| 133 | +$exitCode = $LASTEXITCODE |
| 134 | + |
| 135 | +if ([string]::IsNullOrWhiteSpace($rawOutput)) { |
| 136 | + if ($exitCode -ne 0) { |
| 137 | + throw "PowerForge housekeeping failed with exit code $exitCode and produced no output." |
| 138 | + } |
| 139 | + |
| 140 | + return |
| 141 | +} |
| 142 | + |
| 143 | +try { |
| 144 | + $envelope = $rawOutput | ConvertFrom-Json -Depth 30 |
| 145 | +} catch { |
| 146 | + Write-Host $rawOutput |
| 147 | + throw |
| 148 | +} |
| 149 | + |
| 150 | +Write-HousekeepingSummary -Envelope $envelope |
| 151 | + |
| 152 | +if (-not $envelope.success) { |
| 153 | + Write-Host $rawOutput |
| 154 | + if ($envelope.exitCode) { |
| 155 | + exit [int]$envelope.exitCode |
| 156 | + } |
| 157 | + |
| 158 | + exit 1 |
| 159 | +} |
0 commit comments