Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions .github/workflows/ci-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,35 @@ jobs:
Write-Host "Servico NSSM removido - sera recriado como nativo."
}

# -- Sidecar Decrypt: parar a tarefa agendada ANTES de copiar (fix pos-#569) ---------
#
# Desde o #569 a API descriptografa via HTTP (LayoutParserDecrypt:BaseUrl), nao mais por
# Process.Start. O LayoutParserDecrypt.exe e um exe de CONSOLE (HttpListener em
# http://localhost:<porta>/, sem ServiceBase) - nao pode ser registrado com `sc.exe create`
# (erro 1053). Por isso roda como TAREFA AGENDADA (ONSTART, conta SYSTEM), nome fixo abaixo.
# Aqui so paramos a tarefa e o processo para liberar o .exe antes da copia; o registro e o
# start ficam no step "Registrar e iniciar sidecar Decrypt", depois da copia.
#
# PRE-REQUISITOS DO HOST DEV (NAO verificados pelo CI; confirmados verbalmente pelo dono):
# - o runner pode registrar tarefa agendada como SYSTEM (runner com privilegio de admin);
# - a porta 5220 esta livre (ou escolha outra e alinhe LayoutParserDecrypt__BaseUrl).
- name: Parar sidecar Decrypt (tarefa agendada)
run: |
$taskName = "LayoutParserDecrypt-Sidecar"
$task = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
if ($task) {
Write-Host "Tarefa $taskName existente (estado: $($task.State)) - parando..."
Stop-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
} else {
Write-Host "Tarefa $taskName ainda nao existe - sera criada adiante."
}
# Garante que nenhum LayoutParserDecrypt.exe siga segurando o arquivo (best-effort).
Get-Process -Name "LayoutParserDecrypt" -ErrorAction SilentlyContinue | ForEach-Object {
Write-Host "Encerrando processo LayoutParserDecrypt PID $($_.Id)..."
Stop-Process -Id $_.Id -Force -ErrorAction SilentlyContinue
}
Start-Sleep -Seconds 2

- name: Backup do appsettings e copia dos artefatos
run: |
$DEPLOY_PATH = $env:DEPLOY_PATH_RESOLVED
Expand Down Expand Up @@ -702,6 +731,12 @@ jobs:
# em LowCodeCandidatesBudget.cs. Nada a configurar aqui - o default de 90s ja e seguro.
$envList += "LowCode__RunnerTimeoutSeconds=180"

# LayoutParserDecrypt__BaseUrl - desde o #569 a API descriptografa via HTTP no sidecar
# (step "Registrar e iniciar sidecar Decrypt"). O appsettings.json do destino e PRESERVADO,
# entao a chave do repo nao chega ao dev: sem esta env var, BaseUrl fica vazio, o decryptor
# fica Degraded e o catalogo sobe vazio. Porta 5220 = default do sidecar; manter coerente.
$envList += "LayoutParserDecrypt__BaseUrl=http://localhost:5220/"

# LowCode__RunnerPath - resolvido pelo step de publicacao acima (aponta para
# <deploy>\api\lowcode-runner\LayoutParserLowCodeRunner.exe, copia da pasta Functions/ do
# repo). So e definido quando o runner foi realmente publicado; do contrario a chave nao
Expand Down Expand Up @@ -737,6 +772,84 @@ jobs:
Write-Host "Ambiente do servico configurado ($($envList.Count) variavel(is) definida(s))."
Write-Host " Chaves: $(($envList | ForEach-Object { ($_ -split '=', 2)[0] }) -join ', ')"

# -- Sidecar Decrypt: registrar a tarefa agendada, iniciar e aguardar /health -------
# Roda depois da copia dos artefatos e ANTES do smoke test da API: sem o sidecar de pe,
# o catalogo sobe vazio (decryptor Degraded) e o /health/ready da API nunca fica 200.
# Idempotente: recria a tarefa a cada deploy. Falha o step (com diagnostico, sem segredos -
# o sidecar nao recebe nenhum segredo) se a tarefa nao subir ou o /health nao responder 200.
# Pre-requisitos do host dev: ver comentario do step "Parar sidecar Decrypt".
- name: Registrar e iniciar sidecar Decrypt
run: |
$taskName = "LayoutParserDecrypt-Sidecar"
$porta = 5220
$healthUrl = "http://localhost:$porta/health"
$API_DEST = Join-Path $env:DEPLOY_PATH_RESOLVED "api"
$exePath = Join-Path $API_DEST "LayoutParserDecrypt.exe"

if (-not (Test-Path $exePath)) {
Write-Error "LayoutParserDecrypt.exe nao encontrado em $exePath - o sidecar nao tem o que executar."
exit 1
}

# Porta precisa estar livre (o step anterior ja parou nossa instancia).
$ocupada = Get-NetTCPConnection -LocalPort $porta -State Listen -ErrorAction SilentlyContinue
if ($ocupada) {
$donos = ($ocupada | ForEach-Object {
$p = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
"PID $($_.OwningProcess) ($(if ($p) { $p.ProcessName } else { 'desconhecido' }))"
}) -join ', '
Write-Error "Porta $porta ja esta em uso por: $donos. Libere a porta ou ajuste porta/LayoutParserDecrypt__BaseUrl."
exit 1
}

# Recria a tarefa (idempotente): ONSTART, SYSTEM, sem limite de tempo, restart em falha.
if (Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue) {
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction Stop
}
try {
$action = New-ScheduledTaskAction -Execute $exePath -Argument "$porta" -WorkingDirectory $API_DEST
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) `
-RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) `
-AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -MultipleInstances IgnoreNew
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger `
-Principal $principal -Settings $settings `
-Description "LayoutParserDecrypt sidecar HTTP (porta $porta) - deploy via CI dev" -ErrorAction Stop | Out-Null
Write-Host "Tarefa $taskName registrada (ONSTART, SYSTEM, $exePath $porta)."
Start-ScheduledTask -TaskName $taskName -ErrorAction Stop
} catch {
Write-Error "Falha ao registrar/iniciar a tarefa ${taskName}: $($_.Exception.Message). Verifique se o runner pode criar tarefa agendada como SYSTEM."
exit 1
}

# Aguarda /health responder 200 (ate ~60s).
$ok = $false
for ($i = 1; $i -le 30; $i++) {
try {
$resp = Invoke-WebRequest -Uri $healthUrl -UseBasicParsing -TimeoutSec 3
if ([int]$resp.StatusCode -eq 200) { $ok = $true; break }
} catch { }
Start-Sleep -Seconds 2
}

if (-not $ok) {
Write-Host "--- Diagnostico do sidecar Decrypt ---"
$info = Get-ScheduledTaskInfo -TaskName $taskName -ErrorAction SilentlyContinue
if ($info) { Write-Host "Ultimo resultado da tarefa: $($info.LastTaskResult) (estado: $((Get-ScheduledTask -TaskName $taskName).State))" }
$proc = Get-Process -Name "LayoutParserDecrypt" -ErrorAction SilentlyContinue
Write-Host ("Processo LayoutParserDecrypt: " + $(if ($proc) { "rodando (PID $($proc.Id))" } else { "NAO esta rodando" }))
$logDir = Join-Path $API_DEST "logs"
$ultimo = Get-ChildItem -Path $logDir -Filter "*ecrypt*" -File -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($ultimo) {
Write-Host "--- Fim de $($ultimo.Name) ---"
Get-Content -Path $ultimo.FullName -Tail 20 -ErrorAction SilentlyContinue | ForEach-Object { Write-Host $_ }
}
Write-Error "Sidecar Decrypt nao respondeu HTTP 200 em $healthUrl em ~60s. Deploy de dev abortado antes do smoke test da API."
exit 1
}
Write-Host "Sidecar Decrypt OK: HTTP 200 em $healthUrl."

- name: Iniciar servico e smoke test
run: |
$serviceName = "LayoutParserApi"
Expand Down
Loading