@@ -434,6 +434,52 @@ function Push-SentryApi {
434434 }
435435}
436436
437+ function Push-SentryCheckIn {
438+ param ([string ]$MonitorSlug , [string ]$Status , [string ]$CheckInId )
439+ if ([string ]::IsNullOrWhiteSpace($sentryAuthToken )) { return $null }
440+ try {
441+ $headers = @ { Authorization = " Bearer $sentryAuthToken " ; ' Content-Type' = ' application/json' }
442+ if ([string ]::IsNullOrWhiteSpace($CheckInId )) {
443+ # Initial check-in: POST with monitor_config for auto-creation
444+ $url = " https://sentry.io/api/0/organizations/$sentryOrg /monitors/$MonitorSlug /checkins/"
445+ $body = @ {
446+ status = $Status
447+ monitor_config = @ {
448+ schedule = @ { type = ' interval' ; value = 1 ; unit = ' day' }
449+ checkin_margin = 5
450+ max_runtime = 10
451+ timezone = ' UTC'
452+ }
453+ }
454+ $json = $body | ConvertTo-Json - Compress - Depth 5
455+ $resp = Invoke-RestMethod - Uri $url - Method Post - Headers $headers - Body $json - ErrorAction Stop
456+ $newId = $resp.id
457+ Push-LokiEvent ' deploy_sentry_checkin' ' INFO' " Sentry cron check-in started: $MonitorSlug " @ {
458+ monitor_slug = $MonitorSlug
459+ status = $Status
460+ checkin_id = $newId
461+ }
462+ return $newId
463+ } else {
464+ # Completion check-in: PUT to update existing
465+ $url = " https://sentry.io/api/0/organizations/$sentryOrg /monitors/$MonitorSlug /checkins/$CheckInId /"
466+ $body = @ { status = $Status }
467+ $json = $body | ConvertTo-Json - Compress - Depth 5
468+ Invoke-RestMethod - Uri $url - Method Put - Headers $headers - Body $json - ErrorAction Stop | Out-Null
469+ Push-LokiEvent ' deploy_sentry_checkin' ' INFO' " Sentry cron check-in completed: $MonitorSlug ($Status )" @ {
470+ monitor_slug = $MonitorSlug
471+ status = $Status
472+ checkin_id = $CheckInId
473+ }
474+ return $null
475+ }
476+ } catch {
477+ # Non-fatal: deploy must not fail because Sentry API is down
478+ Write-Warning " Sentry CheckIn ($MonitorSlug /$Status ): $ ( $_.Exception.Message ) "
479+ return $null
480+ }
481+ }
482+
437483if (-not [string ]::IsNullOrWhiteSpace($sentryAuthToken ) -and -not [string ]::IsNullOrWhiteSpace($sentryRelease )) {
438484 Write-Host " Registering Sentry release: $sentryRelease (3 projects)"
439485
@@ -509,6 +555,7 @@ if (-not $skipTests) {
509555 script_count = $testScripts.Count
510556 scripts = ($testScripts | ForEach-Object { $_.Name }) -join ' ,'
511557 }
558+ $checkInId = Push-SentryCheckIn ' post-deploy-tests' ' in_progress'
512559 foreach ($ts in $testScripts ) {
513560 Write-Host " Running: $ ( $ts.Name ) "
514561 $tsStart = Get-Date
@@ -557,6 +604,8 @@ if (-not $skipTests) {
557604 }
558605 }
559606 }
607+ $checkInStatus = if ($postDeployFailed ) { ' error' } else { ' ok' }
608+ Push-SentryCheckIn ' post-deploy-tests' $checkInStatus $checkInId | Out-Null
560609 if ($postDeployFailed ) {
561610 Write-Warning " Post-deploy tests failed. Deploy files are in place but integration is not fully verified."
562611 } else {
0 commit comments