# =============================================================================
# Publish to NPM - workflow EXCLUSIVO de CD (tag v*/release) do pacote raiz
#
# CONSOLIDAÇÃO 2026-08-23 (ADR-006): os triggers push-main/pull_request foram
# REMOVIDOS deste arquivo - o CI de integração em push/PR vive exclusivamente
# no Polyglot CI (.github/workflows/polyglot.yml), cujo job legacy-npm absorviu
# o `npm run verify` (sandbox install) que rodava aqui. Isso elimina o build
# duplicado a cada push de main. Este workflow agora dispara SOMENTE em:
#   - push de tag v*   (ex.: git tag v3.9.0 && git push origin v3.9.0)
#   - release published
# Os dois eventos disparam juntos num release normal; o guard de idempotência
# abaixo torna o segundo disparo um no-op seguro (SKIP, nunca republica).
#
# AUDITORIA 2026-08-23 (frente DevOps/CI) - correções aplicadas:
#
# 1) GUARD DE IDEMPOTÊNCIA NO PUBLISH (causa raiz histórica):
#    Este workflow dispara DUAS vezes por release (push da tag v* +
#    evento release published). Sem guard, a segunda tentativa falha com
#    E403 "cannot overwrite pre-existing version". O publish agora roda
#    APENAS se `npm view izanagi-ai@<versão>` confirmar que a versão ainda
#    NÃO existe no registry. Direção de falha segura: erro de rede também
#    resulta em SKIP (nunca republica nem força).
#    Histórico real: em 2026-08-17 o publish nunca chegou a rodar porque o
#    job build-and-verify falhou antes (`node --test` não encontrava os
#    testes da época); desde 2026-08-18 ambos os workflows falham no
#    postinstall (dist/ ausente em checkout limpo) - fix fora do escopo
#    desta frente.
#
# 2) SUPPLY CHAIN: actions fixadas por SHA de commit completo (imutável).
#    SHAs conferidos na GitHub API em 2026-08-23 (tags = commits):
#      - actions/checkout@v7.0.1   => 3d3c42e5aac5ba805825da76410c181273ba90b1
#      - actions/setup-node@v6.1.0 => 395ad3262231945c25e8478fd5baf05154b1d79f
#    Nunca referenciar tags mutáveis (@v4/@main) diretamente.
#
# 3) LEAST PRIVILEGE:
#    - permissions: contents:read global (antes: GITHUB_TOKEN herdava write
#      em TUDO - visível no log do run 31989520688).
#    - NODE_AUTH_TOKEN/registry-url REMOVIDOS do job build-and-verify:
#      pacote público não precisa de credencial para ci/build/verify, e o
#      token ficava exposto ao env de TODOS os steps (incl. scripts de
#      postinstall de dependências). Credencial só no único step que publica.
#
# 4) PARIDADE DE RUNTIME: Node 24 (igual dev local e igual Polyglot CI,
#    onde o job legacy-npm validou ci/build/test no 24). O 20.x era drift.
#
# 5) PUBLICAÇÃO DIRETA:
#    O npm passou a tratar `npm publish --provenance` como staged publishing
#    em versões recentes, deixando o pacote pendente de aprovação 2FA e fazendo
#    o workflow parecer verde sem atualizar o dist-tag latest. Este CD usa
#    publicação direta autenticada por NPM_TOKEN; o gate build-and-verify
#    continua sendo obrigatório antes do upload.
# =============================================================================

name: Publish to NPM

# CD apenas: nenhum trigger de push de branch ou pull_request.
# CI de push/PR = Polyglot CI (polyglot.yml) - ver ADR-006.
on:
  push:
    tags: ['v*']
  release:
    types: [published]

permissions:
  contents: read

jobs:
  build-and-verify:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      # actions/checkout@v7
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
      # actions/setup-node@v6 - SEM registry-url/token: job não publica nada.
      - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
        with:
          node-version: '24'
          cache: npm
      - name: Install (npm ci without lifecycle scripts)
        run: npm ci --ignore-scripts
      - name: Build
        run: npm run build
      - name: Verify (build + full test suite)
        run: npm test

  publish:
    if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'release'
    needs: build-and-verify
    runs-on: ubuntu-latest
    timeout-minutes: 10
    # O job publica somente depois do gate e precisa apenas ler o checkout.
    permissions:
      contents: read
    steps:
      # actions/checkout@v7
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
      # actions/setup-node@v6 - registry-url apenas aqui: gera o .npmrc com
      # NODE_AUTH_TOKEN injetado pelo setup-node SOMENTE neste job.
      - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
        with:
          node-version: '24'
          cache: npm
          registry-url: 'https://registry.npmjs.org'
      - name: Install (npm ci without lifecycle scripts)
        run: npm ci --ignore-scripts
      - name: Build
        run: npm run build
      # Guard de idempotência: consulta o registry ANTES de publicar.
      # `npm view <pkg>@<ver>` sai 0 quando a versão existe (=> pula o
      # publish) e não-zero quando não existe (=> publica). Republish da
      # mesma versão deixaria de falhar com E403 cannot overwrite.
      - name: Guard - version must not exist in registry yet
        id: version_guard
        run: |
          PKG_VERSION="$(node -p "require('./package.json').version")"
          if npm view "izanagi-ai@${PKG_VERSION}" version >/dev/null 2>&1; then
            echo "already_published=true" >> "$GITHUB_OUTPUT"
            echo "::notice::izanagi-ai@${PKG_VERSION} já existe no registry - npm publish pulado (idempotente)."
          else
            echo "already_published=false" >> "$GITHUB_OUTPUT"
            echo "izanagi-ai@${PKG_VERSION} ainda não publicada - liberando publish."
          fi
      - name: Publish (only if version is new)
        if: steps.version_guard.outputs.already_published == 'false'
        run: npm publish --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
