snglpi/.gitea/workflows/deploy-production.yml
Rafael Lopes bce9a52494 FEAT: Motor de regras único de status/fechamento + mandante configurável
Consolida os dois controladores legados que decidiam status/fechamento de
forma concorrente (processGlpiClosureController + processStatusController)
em um único processTicketLifecycleController, eliminando a dependência do
campo source_last (mantido só como rastro de auditoria) e a flag
ENABLE_STATUS_SYNC (removida). Isso corrige o bug de reabertura: chamados
reabertos no SN voltavam a ser fechados no GLPI porque a regra de
precedência de finalização do fluxo legado forçava o status do GLPI de
volta pro SN.

Correções de bugs encontrados em teste (Frente 1):
- Constraint UNIQUE em ticket_sync.sn_ticket_id + ON CONFLICT DO NOTHING
  na criação do registro, prevenindo duplicação de tickets.
- Fechamento no SN agora é confirmado por leitura ao vivo do status antes
  de marcar o ticket como solved/closed, em vez de confiar só no HTTP 200
  (a API do SN pode retornar sucesso e silenciosamente ignorar um valor de
  estado inválido — descoberto e corrigido também no mandante).
- Nota de encerramento do SN pro GLPI agora é idempotente e criada uma
  única vez por ticket.
- Erros de sincronização passam a ter um limite de tentativas
  (MAX_ERROR_RETRIES) antes de marcar o ticket como error_permanent,
  exigindo intervenção manual em vez de tentar para sempre.
- Chamados criados no GLPI passam a gravar o número do ticket do SN no
  campo externalid.

Nova funcionalidade (Frente 2): quando o SN resolve/encerra um chamado por
conta própria antes do GLPI, além da nota informativa no GLPI (agora com o
nome de quem encerrou, buscado ao vivo via resolved_by/closed_by/
sys_updated_by), o próprio SN recebe um aviso de que a Sothis não vai mais
atender aquele chamado e ele é transferido pra fila de TI da CAOA.

Nova funcionalidade (Mandante, regras 19-22): espelhamento opcional e
configurável de status intermediário (Aguardando Atendimento/Em
Atendimento/Em Espera) entre os dois sistemas, controlado pela env
MANDANTE=GLPI|SNOW. Sem essa env configurada, mantém o comportamento atual
(nenhum espelhamento de status intermediário). Nunca afeta os status finais
(resolvido/encerrado/fora de escopo), que continuam regidos pelas regras
fixas de fechamento.

Corrigido também o workflow de deploy (.gitea/workflows/deploy-production.yml),
que ainda validava os controladores antigos (já removidos) e exigia
ENABLE_STATUS_SYNC=true, o que quebraria o próximo deploy em produção.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 09:45:34 -03:00

94 lines
2.4 KiB
YAML

name: Deploy production
on:
push:
branches:
- master
workflow_dispatch:
jobs:
deploy:
name: Deploy to production VM
runs-on: vm-prod
env:
PROD_DEPLOY_PATH: ${{ vars.PROD_DEPLOY_PATH }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Preflight
shell: bash
run: |
set -euo pipefail
echo "Runner: $(hostname)"
node --version
npm --version
pm2 --version
rsync --version | head -n 1
- name: Validate JavaScript
shell: bash
run: |
set -euo pipefail
node --check cron.js
node --check src/app.js
node --check src/controllers/processTicketLifecycleController.js
node --check src/services/servicenowService.js
node --check src/services/glpiTicketService.js
- name: Deploy files and restart PM2
shell: bash
run: |
set -euo pipefail
DEPLOY_PATH="${PROD_DEPLOY_PATH:-/opt/sn-glpi-sync-new}"
LOCK_FILE="/tmp/sn-glpi-sync-new.deploy.lock"
mkdir -p "$DEPLOY_PATH"
(
flock -n 9 || {
echo "Another deploy is already running."
exit 1
}
rsync -az --delete \
--exclude='.git/' \
--exclude='.gitea/' \
--exclude='.env*' \
--exclude='node_modules/' \
--exclude='logs/' \
./ "$DEPLOY_PATH"/
cd "$DEPLOY_PATH"
test -f .env.production || {
echo "Missing $DEPLOY_PATH/.env.production"
exit 1
}
grep -q '^SERVICENOW_CAOA_TI_GROUP_ID=.\+' .env.production || {
echo "SERVICENOW_CAOA_TI_GROUP_ID must be set in $DEPLOY_PATH/.env.production"
exit 1
}
npm ci --omit=dev
node --check cron.js
node --check src/app.js
node --check src/controllers/processTicketLifecycleController.js
node --check src/services/servicenowService.js
node --check src/services/glpiTicketService.js
pm2 startOrRestart ecosystem.config.js --env production
pm2 save
pm2 list
) 9>"$LOCK_FILE"
- name: Show sync logs
if: always()
shell: bash
run: |
pm2 logs sn-glpi-sync-cron --nostream --lines 80 || true