Skip to content

v1.0.0 — reescrita greenfield do SDK Ruby (nfe-io)#13

Merged
andrenfe merged 23 commits into
masterfrom
next
Jul 2, 2026
Merged

v1.0.0 — reescrita greenfield do SDK Ruby (nfe-io)#13
andrenfe merged 23 commits into
masterfrom
next

Conversation

@andrenfe

@andrenfe andrenfe commented Jul 2, 2026

Copy link
Copy Markdown
Member

Resumo

Reescrita greenfield do SDK Ruby (nfe-io) da NFE.io: 0.3.2 → 1.0.0.
Espelha os SDKs Node.js (v4) e PHP (8.2+) e a nfeio-docs (fonte da verdade),
com zero dependências de runtime (apenas stdlib), Ruby 3.2+ e tipagem
completa via RBS/Steep. Conduzida por specs (OpenSpec).

O que muda

  • Cliente e configuraçãoNfe::Client, Nfe::Configuration, roteamento
    multi-host (modelo de duas chaves), AbstractResource e transporte HTTP
    próprio (retry com backoff + jitter, Retry-After, redação de segredos).
  • 17 recursos cobrindo as famílias de documentos fiscais: emissão e
    consulta das 5 famílias de nota (serviço, produto, consumidor, transporte,
    inbound), empresas, pessoas, inscrições estaduais, webhooks, e os lookups
    (CEP, CNPJ, CPF), além de cálculo de impostos.
  • Emissão RTC (Reforma Tributária) para NFS-e e NF-e/NFC-e.
  • Contrato 202 discriminado (*Pending/*Issued) com polling manual via
    Nfe::FlowStatus.terminal?.
  • Pipeline OpenAPI — value objects + RBS gerados a partir de openapi/*,
    com rake generate:check garantindo que não há drift.
  • Tipos e qualidadesig/ (RBS) + Steep, RuboCop (+rubocop-rspec),
    RSpec com cobertura ≥ 80%.
  • Docs — site Docusaurus-ready (guias + cookbook, slugs pt-BR) e referência
    YARD com a identidade visual NFE.io. MIGRATION.md na raiz.
  • Empacotamento e release — gemspec, samples/, e automação de release
    (CI + publish no RubyGems via OIDC).

Verificação

  • CI verde no branch next (matriz Ruby 3.2 / 3.3 / 3.4): RSpec com
    cobertura, RuboCop, rbs validate, Steep e generate:check.
  • Smoke test read-only contra o sandbox real — validou autenticação,
    roteamento multi-host, o modelo de duas chaves e o mapeamento dos DTOs.
  • Smoke de escrita (caminhos de erro 401/404/422) mapeando exceções
    corretamente contra a API real. Emissão de NF-e exercitada até o payload de
    tax (dependente do regime tributário do cliente).
  • 🐛 O smoke contra a API real revelou 3 descasamentos que a validação
    offline deixou passar (endereço, pageIndex 1-based, environment
    obrigatório) — todos corrigidos e cobertos por teste.

Pós-merge (fora deste PR)

  • Configurar RubyGems trusted publishing (OIDC) ou o secret
    RUBYGEMS_API_KEY, e confirmar ownership do gem nfe-io.
  • Cortar a release (v1.0.0-rc.1 → GA) via tag v*.
  • Publicar a página do SDK Ruby na nfeio-docs.

Notas

  • Breaking change por natureza (reescrita greenfield); guia em
    MIGRATION.md.
  • PR grande em nº de arquivos por incluir código gerado do OpenAPI, specs e docs.

andrenfe added 19 commits June 24, 2026 01:30
Add the OpenSpec change set describing the v1.0.0 rewrite of the nfe-io gem
(zero runtime dependencies, Ruby 3.2+, parity-plus with the Node/PHP SDKs):
9 changes covering foundation, HTTP transport, OpenAPI pipeline, client core,
entity/invoice/lookup resources, RTC (Reforma Tributaria) emission, and release
tooling — plus openspec/project.md context, CHANGESET-OVERVIEW.md, and a
multi-perspective adversarial review report (REVIEW-v1-changeset.md).

Also stop ignoring openspec/ so the plan is tracked, and ignore the local
sibling-repo symlinks (nfeio-docs, client-nodejs, client-php) and build
artifacts (Gemfile.lock, coverage/, .env, *.gem, .steep/).
Begin the v1.0.0 rewrite of the nfe-io gem. Replaces the rest-client-based
v0.3.2 (preserved on the 0.x-legacy branch); no legacy code is reused.

Foundation (add-ruby-foundation):
- gemspec nfe-io 1.0.0, required_ruby_version >= 3.2, ZERO runtime dependencies
- Nfe::Client.new(api_key:) entry point with 17 lazy resource accessors
- Nfe::Configuration multi-base-URL host map; Nfe::FlowStatus terminal helper
- RBS signatures + Steep, RuboCop (+rubocop-rspec), RSpec + SimpleCov (>=80%)
- GitHub Actions CI matrix (Ruby 3.2/3.3/3.4); removes legacy lib/spec/travis

HTTP transport (add-http-transport):
- zero-dependency Net::HTTP transport: per-origin pooled connections (mutex),
  TLS VERIFY_PEER, gzip, timeouts, retry with backoff+jitter + Retry-After
- typed Nfe::Error hierarchy + ErrorFactory; duck-typed logger with secret
  redaction; bodies never logged by default

OpenAPI pipeline (add-openapi-pipeline):
- dev-only generator (scripts/, stdlib only) emitting immutable Data.define
  value objects + from_api hydration + RBS from openapi/ specs synced from
  nfeio-docs; rake generate / generate:check / openapi:sync
- generated tree (1100 files, 11 namespaces) committed and marked
  linguist-generated; CI gate keeps it in sync

Tooling: Docker dev/CI harness (Ruby 3.2/3.3/3.4).

Verified green on the matrix: rspec (213 examples), rubocop, steep, rbs
validate, and generate:check.

BREAKING CHANGE: complete rewrite. The v0.3.x global API (Nfe.api_key(...),
Nfe::ServiceInvoice) is removed in favor of Nfe::Client.new(api_key:). See
MIGRATION.md.
Archive the three implemented-and-verified changes (green on the Ruby
3.2/3.3/3.4 matrix) and apply their deltas to the canonical specs:

- add-ruby-foundation  -> specs/sdk-foundation   (20 requirements)
- add-http-transport   -> specs/http-transport   (20 requirements)
- add-openapi-pipeline -> specs/openapi-pipeline  (16 requirements)

Remaining active changes: add-client-core, add-entity-resources,
add-invoice-resources, add-lookup-resources, add-rtc-invoice-emission,
add-release-tooling.
…resource stubs

Implement the keystone DX layer (add-client-core) wiring the HTTP transport and
generated DTOs into the public client.

- Nfe::Configuration: multi-base-URL host map (single source of truth) with
  family aliases, the two-key model (api_key_for), NFE_API_KEY/NFE_DATA_API_KEY
  env fallback, and ca_file/ca_path/proxy; validates -> Nfe::ConfigurationError.
- Nfe::Client: per-family RetryingTransport(NetHttp) memoized under a Mutex;
  17 thread-safe lazy resource accessors; internal #request raising the typed
  Nfe::Error (via ErrorFactory) on non-2xx (202 is a success).
- Nfe::Resources::AbstractResource: get/post/put/delete, full_path, hydrate
  (klass.from_api), binary download, hydrate_list (page/cursor), and the
  discriminated 202 handle_async_response (Pending/Issued).
- Nfe::RequestOptions (per-call/multi-tenant overrides), Nfe::Pending/Issued,
  Nfe::ListResponse/ListPage, Nfe::IdValidator.
- 17 resource stubs (Nfe::Resources::*) declaring their api_family; business
  methods raise NotImplementedError until the resource changes fill them.
- Adds Nfe::ConfigurationError / Nfe::InvoiceProcessingError to the hierarchy.

Verified green on the Ruby 3.2/3.3/3.4 matrix: rspec 298/0 (~95.6% coverage),
rubocop, steep, rbs validate, generate:check.
…tificate

Fill the four :main-host entity resource stubs (add-entity-resources):

- Nfe::Webhook (HMAC-SHA1 X-Hub-Signature verify_signature — never raises — and
  construct_event) + Nfe::WebhookEvent.
- Nfe::CertificateValidator / CertificateInfo / CertificateStatus (OpenSSL::PKCS12).
- Hand-written DTOs Nfe::Company / LegalPerson / NaturalPerson / WebhookSubscription
  (Data.define + from_api).
- AbstractResource#upload_multipart + #unwrap.
- Companies (CRUD + validate/upload/replace_certificate, certificate status,
  finders), LegalPeople, NaturalPeople, Webhooks (CRUD + test +
  get_available_events + verify_signature).

Verified green on the Ruby 3.2/3.3/3.4 matrix: rspec 404/0 (~95.9% coverage),
rubocop, steep, rbs validate, generate:check.
Archive the two verified changes and apply their deltas to the canonical specs:
- add-client-core      -> specs/client-core (20 requirements)
- add-entity-resources -> specs/entity-resources (13) + webhook-signature-verification (8)

Remaining active changes: add-invoice-resources, add-lookup-resources,
add-rtc-invoice-emission, add-release-tooling.
Fill the five invoice resource stubs against api.nfe.io (service NFS-e,
:main) and api.nfse.io (product NF-e, consumer NFC-e, transportation CT-e,
inbound NF-e — all :cte):

- Discriminated create: HTTP 202 -> *Pending (invoice_id from Location),
  HTTP 201 -> *Issued (hydrated). idempotency_key: -> Idempotency-Key header;
  per-call request_options: forwarded without mutating the Client.
- service_invoices: create / list (page-style) / retrieve / cancel /
  send_email / download_pdf|xml (bytes) / get_status (derived, no extra HTTP).
- product_invoices: cursor list (+environment required), state-tax create,
  items/events, correction letter (15-1000 chars), disable/disable_range;
  download_* return Nfe::NfeFileResource (URI, not bytes).
- consumer_invoices: NFC-e parity-plus; downloads return bytes.
- transportation_invoices + inbound_product_invoices: inbound/query surface.
- Hand-written DTOs under lib/nfe/resources/dto/ (Nfe::ServiceInvoice,
  ProductInvoice, ConsumerInvoice, NfeFileResource, inbound settings/metadata)
  + discriminated response VOs under lib/nfe/resources/responses/.
- Nfe::ListResponse now includes Enumerable (each -> data), completing the
  client-core contract the design assumed.

Docs aligned to the shipped convention: hand-written DTOs live in
lib/nfe/resources/dto/ as top-level Nfe::* (matching entity-resources), not
the older lib/nfe/models/ / Nfe::Models:: plan. README documents the
discriminated return, the download divergence and the manual polling loop.

Verified green on Ruby 3.2/3.3/3.4: rspec 525/0 (~96.9% coverage), rubocop,
steep, rbs validate, generate:check. Change archived + specs synced
(specs/invoice-resources, 16 requirements). Section 13 (manual sandbox smoke
tests) left open: opt-in, outside CI.
Fill the 8 lookup/query resource stubs across five host families
(add-lookup-resources):

- addresses (:addresses) — CEP lookup, $filter search, term lookup.
- legal_entity_lookup (:legal_entity) — basicInfo + 3 state-tax CNPJ lookups.
- natural_person_lookup (:natural_person) — CPF status (DateNormalizer for
  the birth date: accepts String/Date/Time/DateTime).
- product_invoice_query (:nfe_query) — NF-e by access key + pdf/xml bytes +
  events.
- consumer_invoice_query (:nfe_query) — NFC-e coupon (CFe-SAT) by access key +
  xml. Distinct from consumer_invoices (emission).
- tax_calculation (:cte) — /tax-rules/{tenant}/engine/calculate (reuses the
  generated CalculoImpostosV1::CalculateResponse).
- tax_codes (:cte) — 4 paginated 1-based code lists.
- state_taxes (:cte) — CRUD with the {stateTax:} envelope, cursor-style list.

Support: Nfe::DateNormalizer (stdlib date/time, ISO round-trip validation);
Nfe::ListResponse already Enumerable; all resources fail fast (no HTTP) on
invalid ids via Nfe::IdValidator (cep/cnpj/cpf/state/access_key).

Adversarial review (4 dimensions vs the openapi/* specs + Node/PHP SDKs)
caught 11 real defects the agent-written specs had masked — fixed here:
- Wrong API keys that were always nil against the live API: Address
  neighborhood->district (+nested city{code,name}, numberMin/Max);
  ProductInvoiceDetails status->currentStatus (+ dropped bogus top-level
  accessKey); LegalEntity statusDate/companySize/openingDate/emails ->
  statusOn/size/openedOn/email; TaxCoupon totals/payment/delivery/item/
  additionalInformation/buyer remapped to the real CFe-SAT shape.
- LegalEntity state-tax responses given their own shape (StateTaxLegalEntity
  with stateTaxes[]) instead of reusing the basicInfo DTO.
- Masking specs rewritten to assert against realistic payloads (real
  camelCase keys + enum values) so mismapping can no longer hide.
- tax_calculation tenant_id coerced before strip (typed error, not NoMethodError).

Configuration: documented that :cte intentionally uses api_key (not a data
family), a deliberate divergence from the Node SDK.

Verified green on Ruby 3.2/3.3/3.4: rspec 604/0 (~97.9% coverage), rubocop,
steep, rbs validate, generate:check. Change archived + specs synced
(specs/lookup-resources, 13 requirements). Section 13 (manual sandbox smoke
tests) left open: opt-in, outside CI.
Add the two opt-in Reforma Tributária (RTC) emission resources as
paridade-plus addons (Client now exposes 19 accessors: 17 canonical + 2 RTC):

- service_invoices_rtc (:main, api.nfe.io/v1) — create (discriminated 202
  Pending / 201 Issued), retrieve, cancel, download_cancellation_xml (ADN,
  post-Cancelled). Reuses the classic Nfe::ServiceInvoice DTO (the
  service-invoice-rtc spec defines only the NFSeRequest request shape).
- product_invoices_rtc (:cte, api.nfse.io/v2) — full classic surface
  (create, create_with_state_tax, retrieve, cursor list, cancel, items,
  events, pdf/xml/rejection/epec downloads, correction letter, disable /
  disable_range), hydrating the generated ProductInvoiceRtcV1 DTOs
  (InvoiceResource, RequestCancellationResource, DisablementResource, ...).
  Downloads return Nfe::NfeFileResource (uri), matching the classic resource.

Both RTC layouts are selected by the presence of the ibsCbs (NFS-e) /
items[].tax.IBSCBS (product) group in the payload — same endpoints, no
discriminator header/param. create(data:) takes a Hash with camelCase keys
(generated DTOs deserialize only; the request DTO documents the shape).
Generated RTC DTOs already emitted (generator auto-globs openapi/*).

Adversarial review (3 dims vs the RTC openapi specs + classic resources)
confirmed no shipping-code defects; it caught 2 spec-realism issues (fixed):
the IBSCBS/ibsCbs fixtures used fabricated keys (cst/classificationCode,
operationType "Standard") and omitted the required operationIndicator/classCode
— rewritten to the real situationCode/classCode + operationIndicator so the
specs are accurate regression guards and copyable usage docs.

.rubocop.yml: allow `q` (API search-query param) as a short keyword name.
README documents the RTC opt-in, the ibsCbs/IBSCBS layout selector and the
manual polling loop.

Verified green on Ruby 3.2/3.3/3.4: rspec 647/0 (~98.4% coverage), rubocop,
steep, rbs validate, generate:check. Archived + specs synced
(specs/rtc-invoice-emission, 16 requirements). Section 12 (create_and_wait/
batch, runtime field validation, future RTC events, tax engine) is the
explicit out-of-scope record.
Finalize v1.0.0 for release (add-release-tooling):

- nfe-io.gemspec: documentation_uri added; verified zero runtime deps,
  required_ruby_version >= 3.2, ships lib/**/*.rb + sig/**/*.rbs +
  README/MIGRATION/CHANGELOG/LICENSE only (no spec/samples/skills/openspec).
  Built gem: 1248 files, 621 .rbs, 550 generated, runtime_dependencies == [].
- Rakefile: require "bundler/gem_tasks" (build/install/release).
- .rubocop.yml: exclude samples/** (runnable examples).
- CHANGELOG.md: Keep a Changelog + SemVer, full 1.0.0 entry (pt-BR).
- MIGRATION.md: exhaustive v0.3.x -> v1.0.0 guide (config, class/method maps,
  errors, 202 polling, webhook HMAC-SHA1 over raw bytes, downloads, deferred
  features, vanilla + Rails appendices). Corrected: advanced options
  (open_timeout/base_url_overrides/ca_file/ca_path/proxy) live on
  Nfe::Configuration and are injected via configuration:, not on Client.new.
- README.md: expanded (badges, requisitos, quickstart, configuração + the
  Configuration-injection fix, sandbox vs produção, resource map, per-resource
  examples, errors, downloads, webhooks, versioning, type-checking).
- CONTRIBUTING.md: branches, setup, toolchain, generated-files policy, commits.
- samples/: 13 runnable examples + config.rb + .env.example + README.
- scripts/release.sh: version bump (dotted prerelease form), CHANGELOG rotate,
  gate, tag + push; --dry-run/--skip-tests/--skip-git; no local gem push.
- .github/workflows/release.yml: tag-triggered verify matrix (3.2/3.3/3.4) +
  publish via RubyGems OIDC trusted publishing (+ GEM_HOST_API_KEY fallback),
  version-assertion, GitHub Release, prerelease handling.
- skills/nfeio-ruby-sdk/: AI skill SKILL.md + 5 reference files.

Verified green on Ruby 3.2/3.3/3.4: rspec 647/0 (~98.4% coverage), rubocop,
steep, rbs validate, generate:check; gem builds clean with zero runtime deps;
release.sh syntax + --help OK; release.yml valid YAML. Archived + specs synced
(specs/release-tooling, 15 requirements).

DEFERRED TO MAINTAINER (outward-facing / env-gated, kept unchecked in tasks):
- §10 update the external nfeio-docs repo page (coordinate with docs team).
- §11.6/§11.7 run samples against sandbox + full release.sh --dry-run (needs
  credentials + a real release env with ruby/gh on master).
- §12 cut the actual v1.0.0-rc.1 -> GA release (tag push triggers publish),
  announce, beta period, GA cutover + README banner removal.

This completes the v1.0.0 greenfield change set: all 9 OpenSpec changes
implemented, verified, archived (10 capability specs).
The API key does NOT separate production vs. test — that is determined by the
account configuration at https://app.nfe.io (server-side). The Client
`environment:` symbol (:production/:development) is reserved for future use:
today it is validated but has no effect on endpoints, keys, or behavior
(confirmed against the Node SDK, where `environment` likewise does not switch
prod/test). Fixed the wrong 'separation is done by the API key' claim in
README, MIGRATION, the nfeio-ruby-sdk skill, and the Nfe::Configuration doc
comment. The separate product/consumer `environment:` String ('Production'/
'Test', the SEFAZ environment on list/emit) is unchanged. Code behavior
unchanged (comment/doc-only); green on Ruby 3.2/3.3/3.4 (647/0).
Add a canonical docs/ tree for the SDK, authored Docusaurus 3 (MDX) ready so it
copy/pastes into nfeio-docs with no rework, plus a YARD API reference themed
with the NFE.io brand identity.

Docs tree (pt-BR, MDX-safe, :::admonitions, frontmatter on every page):
- docs/README.md — landing mirroring bibliotecas/php.md (IntegrationLayout
  frontmatter: provider/badge/heroImage/ctaUrl).
- 9 guides: getting-started, configuration, async-and-polling, errors,
  webhooks, pagination, downloads, multi-host-routing, rtc-emission.
- docs/resources/ cookbook — one page per resource (17 canonical + an RTC
  page), with real method signatures read from lib/nfe/resources/.
- _category_.json files + sidebar_position for the Docusaurus sidebar.
- docs/MAINTAINING.md — internal: the copy/paste sync flow into nfeio-docs
  (bibliotecas/ruby/ + static/api/ruby/).
Cross-links verified (0 broken); no bare <​/{ in prose (MDX-safe).

YARD API reference with NFE.io identity:
- docs/yard-theme/ — a --template-path override: brand CSS (Roboto, #333 text,
  120deg gradient header banner with the white logo, brand-colored headings/
  links/code/tags), favicon, applied to main + nav pages. Self-contained
  (logos as data-URIs) so docs/api/ works after being moved into Docusaurus
  static/. Brand values from the official media-kit (#7AEA53 / #5DD0F2).
- .yardopts (ASCII title — an accented title broke YARD's UTF-8 layout),
  Rakefile `rake doc` (guarded YARD::Rake::YardocTask), gemspec yard dev-dep,
  .gitignore docs/api/, .rubocop.yml excludes docs/.

Production vs. test is documented correctly throughout (account-side at
app.nfe.io; the Client environment: symbol is reserved for future use).

Verified green on Ruby 3.2/3.3/3.4: rspec 647/0, rubocop, steep, rbs,
generate:check; gem builds with zero runtime deps; rake doc -> 122 themed pages.
Make the published URLs explicit and pt-BR via the Docusaurus `slug` frontmatter
instead of being derived from the (English) filenames — more predictable and
easier to identify in external files.

- Add a relative `slug:` (pt-BR) to all 9 guides + 18 cookbook pages, e.g.
  configuration.md -> `configuracao`, recursos/companies.md -> `empresas`
  (-> .../recursos/empresas). The landing (README.md) stays the section index.
- Rename docs/resources/ -> docs/recursos/ so the directory segment is pt-BR
  too; fix the README + MAINTAINING references (lib/nfe/resources/ untouched).
- recursos/_category_.json gets a generated-index (slug: recursos) so the
  cookbook folder has a category landing.
- Document the slug convention in docs/MAINTAINING.md.

Validated: 29 files, frontmatter on every page, 0 broken cross-links, 0 slug
collisions, MDX-safe. Filenames stay English; slugs (frontmatter) drive the URLs.
The landing (README.md -> index.md in nfeio-docs) now carries
slug: /desenvolvedores/bibliotecas/ruby, mirroring bibliotecas/nodejs/index.md,
so the Ruby SDK section owns its canonical URL. Sub-pages keep relative pt-BR
slugs.
…andbox)

O smoke test read-only contra o sandbox (samples/smoke_readonly.rb) revelou
três pontos em que o SDK divergia da API real — todos corrigidos e cobertos:

- addresses.lookup_by_postal_code: a API retorna { "address": {...} } (singular),
  não { "addresses": [...] } (o openapi/consulta-endereco.yaml está incorreto
  para este endpoint). AddressLookupResponse.from_api passa a aceitar AMBOS os
  wrappers, normalizando o singular numa lista de um item.
- companies.list: a API exige pageIndex >= 1 (1-based). O page_index público
  continua 0-based mas é enviado como page_index + 1 (a tradução do request
  estava faltando; a do response já existia em resolve_page_index).
- consumer_invoices.list: a API exige o parâmetro environment ("Production"/
  "Test"); agora é keyword obrigatória + require_environment, espelhando
  product_invoices.list. Doc do cookbook atualizado.

Adiciona samples/smoke_readonly.rb — smoke test read-only (não grava nada) que
valida auth, roteamento multi-host, o modelo de duas chaves e o mapeamento dos
DTOs contra respostas reais (lê samples/.env, que é gitignored).

Validado contra o sandbox real: addresses/tax_codes/legal_entity/companies.list/
product_invoices.list/consumer_invoices.list/state_taxes.list todos OK.
Verde no Docker 3.2/3.3/3.4: rspec 651/0, rubocop, steep, rbs, generate:check.

Não-bugs observados no sandbox (sem ação no SDK): service_invoices.list devolve
503 (serviço NFS-e instável; SDK mapeia para ServerError corretamente);
companies.retrieve/legal_people.list/natural_people.list falham porque o company
de teste existe no host :cte (api.nfse.io) e não no :main (api.nfe.io) — paths e
erros mapeados corretamente.
- ci.yml: dispara push/PR tambem em 'next', para validar o codigo v1 no
  GitHub antes da virada next -> master (o gate so rodava no Docker local).
- release.yml: adiciona 'rbs validate' ao job verify, igualando-o ao ci.yml
  (RSpec c/ cobertura, RuboCop, RBS validate, Steep, generate:check).
Silencia o aviso de depreciacao do Node 20 nos runners do GitHub Actions:
o checkout@v4 tem como alvo o Node 20 e era forcado a rodar no Node 24.
Comment thread lib/nfe/resources/companies.rb Fixed
@andrenfe andrenfe self-assigned this Jul 2, 2026
andrenfe added 4 commits July 1, 2026 23:19
…QL rb/polynomial-redos)

A regex /\A[^\s@]+@[^\s@]+\.[^\s@]+\z/ tinha classes de caractere sobrepostas
(o '.' cabe em [^\s@]), causando backtracking polinomial em entradas
adversarias. Substituida por uma verificacao estrutural linear e de semantica
equivalente: exatamente um '@', sem espacos, e dominio com rotulos nao-vazios
antes/depois do ponto. Alerta de alta severidade apontado pelo CodeQL no PR #13.
Adapta o job publish para a OIDC API Key Role criada no RubyGems para o gem
nfe-io, passando role-to-assume a rubygems/configure-rubygems-credentials
(bump v1.0.0 -> v2.1.0, que suporta o parametro). Dispensa API key de longa
duracao; o fallback por RUBYGEMS_API_KEY segue como rede de seguranca.
Adota o mecanismo recomendado (guides.rubygems.org/trusted-publishing): o
Trusted Publisher e cadastrado na pagina do gem (repo + workflow release.yml),
e a action troca o token OIDC sem role-to-assume. Remove o identificador de
role do workflow; fallback por RUBYGEMS_API_KEY segue como rede de seguranca.
@andrenfe andrenfe merged commit f52b89c into master Jul 2, 2026
8 checks passed
@andrenfe andrenfe deleted the next branch July 2, 2026 03:17
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.

2 participants