<# .SYNOPSIS Beobachtet den neuesten GitHub Actions Run bis zum Abschluss. .PARAMETER WaitForNew Sekunden Wartezeit bis der Run nach einem Push erscheint (Default: 15). 0 = Run existiert bereits. .PARAMETER Timeout Maximale Wartezeit in Sekunden (Default: 300). .PARAMETER ExpectedSha Optionaler Git-SHA (kurz oder lang). Wenn angegeben, wartet das Skript bis ein Run mit diesem SHA erscheint (max. 60s), statt einfach den neuesten Run zu nehmen. .EXAMPLE & watch-pipeline.ps1 # Neuester Run & watch-pipeline.ps1 -WaitForNew 0 # Sofort, neuester Run & watch-pipeline.ps1 -ExpectedSha abc1234 # Warte auf Run fuer Commit #> param( [int]$WaitForNew = 15, [int]$Timeout = 300, [string]$ExpectedSha = "" ) $repo = "jreinemann-euris/bollwerk" $poll = 10 # --- Warten --- if ($WaitForNew -gt 0) { Write-Host "Warte ${WaitForNew}s auf Pipeline-Start..." -ForegroundColor DarkGray Start-Sleep -Seconds $WaitForNew } # --- Run-ID ermitteln --- $runId = "" if ($ExpectedSha) { # Warte bis ein Run mit dem erwarteten SHA erscheint $shaWaitMax = 60 $shaWaitElapsed = 0 Write-Host "Suche Run fuer Commit $ExpectedSha ..." -ForegroundColor DarkGray while ($shaWaitElapsed -lt $shaWaitMax) { $candidateId = (gh run list --repo $repo --limit 1 --json databaseId --jq '.[0].databaseId' 2>$null).Trim() $candidateSha = (gh run list --repo $repo --limit 1 --json headSha --jq '.[0].headSha' 2>$null).Trim() if ($candidateSha -like "$ExpectedSha*") { $runId = $candidateId break } Start-Sleep -Seconds 5 $shaWaitElapsed += 5 } if (-not $runId) { Write-Host "Kein Run fuer SHA $ExpectedSha gefunden (${shaWaitMax}s gewartet)." -ForegroundColor Yellow Write-Host "Pipeline wurde vermutlich nicht getriggert (Pfad-Filter?)." exit 0 } } else { $runId = (gh run list --repo $repo --limit 1 --json databaseId --jq '.[0].databaseId' 2>$null).Trim() } if (-not $runId) { Write-Host "FEHLER: Kein Run gefunden." -ForegroundColor Red exit 1 } $runName = (gh run view --repo $repo $runId --json name --jq '.name' 2>$null).Trim() $sha = (gh run view --repo $repo $runId --json headSha --jq '.headSha' 2>$null).Trim() if ($sha.Length -gt 7) { $sha = $sha.Substring(0,7) } Write-Host "Run $runId ($runName) @ $sha" -ForegroundColor Cyan # --- Pollen --- $start = Get-Date while ($true) { $elapsed = [int]((Get-Date) - $start).TotalSeconds if ($elapsed -gt $Timeout) { Write-Host "Timeout nach ${Timeout}s." -ForegroundColor Yellow exit 2 } $status = (gh run view --repo $repo $runId --json status --jq '.status' 2>$null).Trim() $conclusion = (gh run view --repo $repo $runId --json conclusion --jq '.conclusion' 2>$null).Trim() $min = [math]::Floor($elapsed / 60) $sec = $elapsed % 60 $ts = "${min}:$("{0:00}" -f $sec)" if ($status -eq "completed") { if ($conclusion -eq "success") { Write-Host "Pipeline GRUEN ($ts)" -ForegroundColor Green } else { Write-Host "Pipeline FEHLGESCHLAGEN: $conclusion ($ts)" -ForegroundColor Red } break } Write-Host " [$ts] $status ..." -ForegroundColor DarkGray Start-Sleep -Seconds $poll } # --- Warnungen ausgeben --- $viewOutput = gh run view --repo $repo $runId 2>$null $warnings = $viewOutput | Where-Object { $_ -match '^\s*!' } if ($warnings) { Write-Host "" Write-Host "Warnungen:" -ForegroundColor Yellow foreach ($w in $warnings) { Write-Host " $($w.Trim())" -ForegroundColor Yellow } } # --- Exit-Code --- if ($conclusion -eq "success") { exit 0 } else { Write-Host "Details: gh run view --repo $repo $runId --log-failed" exit 1 }