Skip to content

CI: publicar as tabelas IBPT no R2 via GitHub Actions - #6

Merged
rhfranzoni merged 3 commits into
masterfrom
claude/vibrant-hypatia-w5qfyr
Sep 29, 2026
Merged

rhfranzoni merged 3 commits into
masterfrom
claude/vibrant-hypatia-w5qfyr

Conversation

@rhfranzoni

@rhfranzoni rhfranzoni commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Refs #2

Motivação

Sugestão do Sérgio: como este repositório serve só para as tabelas IBPT, o push na master já deve publicar em https://ibpt.nfe.io (bucket R2 ibpt), sem depender de alguém rodar o publish-r2.js na própria máquina.

Mudanças

.github/workflows/publish.yml (Publish IBPT tables), com dois jobs:

  • publish: roda publish-r2.js --apply, que publica só o que mudou.
    • Dispara em push na master que altere lc116/, nbs/, ncm/, lc116-nbs-map.json, o script ou o workflow.
    • Dispara também em execução manual com apply, que só é aceita na master.
    • Roda no environment production, o único lugar onde fica o token de escrita.
    • Fica no grupo de concurrency publish-ibpt, sem cancelamento, então duas publicações nunca rodam juntas.
  • dry-run: simulação, com o resultado no resumo do job.
    • Roda em PR e em execução manual sem apply.
    • Usa um token somente leitura.
    • Fica num grupo de concurrency por branch, então nunca substitui uma publicação pendente.
  • Opções da execução manual: tables, apply e allow_mass_delete. A última serve para quando uma versão nova do IBPT remove mais de 25% de uma tabela.
  • Segurança:
    • permissions: contents: read;
    • PRs de fork não rodam;
    • os inputs vão por variável de ambiente, nunca interpolados no shell;
    • tables é validado pelo script contra lc116/nbs/ncm;
    • o token de escrita nunca fica disponível para código de PR, mesmo que o PR altere o workflow, porque o environment production só libera os secrets para a master. Veja o review do Copilot.

publish-r2.js: fixa o byte de SO do cabeçalho gzip em 255. Antes o Linux gerava 3 e o Windows 10, então o CI via como alterado tudo o que tinha sido publicado do Windows. Agora o ETag é o mesmo em qualquer máquina.

package-lock.json: adicionado, para o CI usar npm ci.

docs/atualizacao-tabela-ibpt.md: fluxo com o Action, credenciais e execução manual.

Configuração necessária (admin)

Onde Secret Token do R2 (bucket ibpt)
Repositório R2_ACCOUNT_ID ID da conta NFE.io
Repositório R2_READONLY_ACCESS_KEY_ID, R2_READONLY_SECRET_ACCESS_KEY Object Read only, sem expiração
Environment production R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY Object Read & Write, sem expiração
  • O environment production precisa estar com Deployment branches and tags → Selected branches → master.
  • R2_ACCESS_KEY_ID/R2_SECRET_ACCESS_KEY não devem existir como secrets do repositório.

Validação

  • actionlint 1.7.7 sem erros.

  • A lógica de cada job foi testada com um node falso:

    Job e situação Comando / resultado
    publish em push --apply
    publish manual, ncm, mass delete --tables ncm --apply --allow-mass-delete
    publish sem secrets erro e sai com 1
    dry-run em PR sem --apply
    dry-run manual --tables lc116
    dry-run sem secrets aviso e sai com 0
  • Antes da separação de credenciais, uma simulação real contra o bucket confirmou o estado publicado em 29/09:

    • lc116: remote=5512, delete=0, incluindo os 2 manuais de RJ protegidos;
    • nbs: remote=23220, delete=0.
  • O gzip com o byte fixado descompacta idêntico ao arquivo original.

  • CodeQL sem alertas.

⚠️ Ao fazer o merge

  • O merge toca no script e no workflow, então dispara uma publicação completa. Por causa da mudança no gzip, ela reenvia os cerca de 313 mil arquivos uma vez (dados iguais, só o gzip muda), e pode levar de 30 a 60 minutos.
  • Faça o merge depois que a publicação manual da NCM em andamento terminar.
  • Configure os secrets e o environment antes do merge. Se não estiverem prontos, o job publish falha, e depois de configurar basta fazer re-run.

🤖 Generated with Claude Code

https://claude.ai/code/session_015op3Yt7XX876JEcM3LhWJT

- push to master touching lc116/, nbs/, ncm/, the map or the script runs
  publish-r2.js --apply (only what changed is uploaded)
- pull requests run the dry-run, with the result in the job summary
- manual runs are dry-run by default, with apply and allow_mass_delete options
- one publish at a time (concurrency group, no cancel)
- needs the R2_ACCOUNT_ID, R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY secrets;
  without them the PR dry-run is skipped with a warning and push fails

publish-r2.js fixes the gzip header OS byte to 255, so the md5/etag is the same
on linux (CI) and windows; package-lock.json added for npm ci.

Refs #2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015op3Yt7XX876JEcM3LhWJT
The v4 actions target the deprecated Node 20 runtime and GitHub already warns
that they are being forced to Node 24.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015op3Yt7XX876JEcM3LhWJT
@sergiojrdotnet
sergiojrdotnet requested review from sergiojrdotnet and a balanced review from Copilot September 29, 2026 18:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Write credentials are exposed to PR-controlled code, and shared concurrency can discard a pending production publication.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Automatiza a publicação das tabelas IBPT no Cloudflare R2 via GitHub Actions.

Changes:

  • Adiciona workflow para simulação e publicação.
  • Torna o gzip consistente entre sistemas operacionais.
  • Documenta o fluxo e fixa dependências com lockfile.
File Description
.github/​workflows/​publish.yml Configura publicação e simulação no CI.
publish-r2.js Normaliza o byte de SO do gzip.
package-lock.json Permite instalações reproduzíveis com npm ci.
docs/​atualizacao-tabela-ibpt.md Documenta o fluxo automatizado.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/publish.yml
Comment thread .github/workflows/publish.yml Outdated
Review findings on the publish workflow:

- pull requests from branches of this repository received the write token and
  ran PR-controlled code (package.json, script, workflow). The publish job now
  runs in the 'production' environment, whose secrets are restricted to master,
  and dry-runs (PR and manual without apply) use a separate Object Read only
  token (R2_READONLY_ACCESS_KEY_ID / R2_READONLY_SECRET_ACCESS_KEY)
- a dry-run sharing the concurrency group could replace a pending publish.
  Concurrency is now per job: publishes share publish-ibpt (no cancel),
  dry-runs use a per-ref group

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015op3Yt7XX876JEcM3LhWJT
@rhfranzoni
rhfranzoni merged commit cc1e500 into master Sep 29, 2026
4 checks passed
@rhfranzoni
rhfranzoni deleted the claude/vibrant-hypatia-w5qfyr branch September 29, 2026 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants