From 8e29055741d1a4d065ff8421bc2f5a3b7b69133d Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Sun, 17 May 2026 17:22:17 -0300 Subject: [PATCH 1/9] chore(cli): bump serverust-cli 0.1.6 -> 0.3.0 (align workspace) --- Cargo.lock | 2 +- serverust-cli/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7ce67a..1aa8c1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2687,7 +2687,7 @@ dependencies = [ [[package]] name = "serverust-cli" -version = "0.1.6" +version = "0.3.0" dependencies = [ "anyhow", "aws-config", diff --git a/serverust-cli/Cargo.toml b/serverust-cli/Cargo.toml index 881b7c4..cc47fdd 100644 --- a/serverust-cli/Cargo.toml +++ b/serverust-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serverust-cli" -version = "0.1.6" +version = "0.3.0" edition.workspace = true rust-version.workspace = true authors.workspace = true From b2034d3f2b60d1fd00c8934f9bcb9d252aaa6560 Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Sun, 17 May 2026 17:31:27 -0300 Subject: [PATCH 2/9] =?UTF-8?q?chore(release):=20tooling=20p=C3=B3s-v0.3.0?= =?UTF-8?q?=20=E2=80=94=20cargo-release=20+=20cargo-deny=20+=20per-crate?= =?UTF-8?q?=20tags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aplica recomendações da pesquisa "como tokio/axum fazem release": - `release.toml` — config cargo-release com per-crate tags (`-v`), SSH-signed, push automático, hook quality_changelog. Substitui as 7 etapas manuais da release v0.3.0 por `cargo release patch --workspace --execute`. - `deny.toml` — config cargo-deny com allowlist SPDX restritiva, deny em yanked/unknown-registry/wildcards, scheduled scan semanal. - `.github/workflows/cargo-deny.yml` — CI em PR + push main + cron semanal (segunda 05:23 UTC para pegar advisories novas sem mudança no código). - `docs/development/release-checklist.md` reescrito com 3 fluxos documentados (cargo-release / cargo publish --workspace / manual sequencial) + pré-flight obrigatório (SSH signing, cargo login, deny). - `CLAUDE.md` atualizado: per-crate independent versioning a partir de v0.4, fluxo cargo-release recomendado, fluxo manual como alternativa, pré-flight documentado. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/cargo-deny.yml | 31 +++++++++ CLAUDE.md | 40 ++++++++--- deny.toml | 54 +++++++++++++++ docs/development/release-checklist.md | 96 +++++++++++++++++++++++---- release.toml | 46 +++++++++++++ 5 files changed, 245 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/cargo-deny.yml create mode 100644 deny.toml create mode 100644 release.toml diff --git a/.github/workflows/cargo-deny.yml b/.github/workflows/cargo-deny.yml new file mode 100644 index 0000000..c0ad92d --- /dev/null +++ b/.github/workflows/cargo-deny.yml @@ -0,0 +1,31 @@ +name: cargo-deny + +on: + pull_request: + paths: + - "**/Cargo.toml" + - "Cargo.lock" + - "deny.toml" + - ".github/workflows/cargo-deny.yml" + push: + branches: [main] + paths: + - "**/Cargo.toml" + - "Cargo.lock" + - "deny.toml" + schedule: + # Roda semanalmente para pegar advisories novas mesmo sem mudanças. + - cron: "23 5 * * 1" # segunda 05:23 UTC + +jobs: + check: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + - uses: EmbarkStudios/cargo-deny-action@v2 + with: + # `check all` = advisories + licenses + bans + sources. + command: check all + arguments: --workspace diff --git a/CLAUDE.md b/CLAUDE.md index 635c42c..f509bde 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,14 +24,38 @@ Estas propriedades são compromissos públicos. Violá-las exige uma nova ADR ap ## Processo de Release -1. Incrementar versão em `Cargo.toml` (workspace `version`). -2. Atualizar `CHANGELOG.md` — mover items de `[Unreleased]` para a nova versão com data. -3. Rodar `scripts/quality_changelog.sh` — deve passar. -4. Rodar `scripts/benchmark_ci.sh` — registrar saída em `docs/product/metrics/history.json`. -5. Rodar `scripts/benchmark_competitive.sh` — atualizar `docs/product/competitors/release-competitive-log.md`. -6. Criar tag git: `git tag -s v -m "Release v"`. -7. Publicar crates na ordem: `serverust-macros` → `serverust-core` → `serverust-telemetry` → `serverust-lambda` → `serverust-cli`. -8. Confirmar que CI passou **com a tag** (histórico: v0.1.1 e v0.1.2 foram publicadas sem tag — não repetir). +A partir de v0.4: **per-crate independent versioning** (estilo tokio/axum). Tag por crate `-vX.Y.Z`. Pré-v0.4 usava workspace-wide unified versioning. + +### Fluxo recomendado (cargo-release) + +```bash +# Patch release de um crate específico: +cargo release patch -p serverust-events --execute + +# Workspace inteiro (bump + tag + publish na ordem certa, tudo atômico): +cargo release patch --workspace --execute +``` + +`cargo-release` (config em `release.toml`) faz: bump → CHANGELOG date → commit → tag SSH-signed → push → `cargo publish` na ordem de dependência. + +### Fluxo manual (alternativa) + +1. Incrementar `version` no(s) `Cargo.toml` do(s) crate(s) afetado(s). +2. Atualizar refs path-deps internas (`version = "X.Y.Z"`). +3. Mover items de `[Unreleased]` para nova versão com data no `CHANGELOG.md`. +4. Rodar `scripts/quality_changelog.sh` — deve passar. +5. Rodar `scripts/benchmark_ci.sh` + `scripts/metrics_append.sh `. +6. Rodar `scripts/benchmark_competitive.sh` (atualiza `release-competitive-log.md`). +7. Criar tag git assinada: `git tag -s -v -m "Release v"` (per-crate) ou `git tag -s v` (workspace). +8. Publicar (Cargo 1.90+): `cargo publish --workspace` resolve ordem. Ou sequencial: `serverust-macros` → `serverust-core` → `serverust-telemetry` → `serverust-events` → `serverust-lambda` → `serverust-cli`. +9. Confirmar que CI passou **com a tag** (histórico: v0.1.1 e v0.1.2 foram publicadas sem tag — não repetir). + +### Pré-flight obrigatório + +- SSH signing configurado (`gpg.format = ssh`, `user.signingkey = ~/.ssh/id_*.pub`, `tag.gpgsign = true`). +- Public key adicionada como **Signing key** em GitHub settings. +- `cargo login` configurado. +- `cargo deny check` verde (CI: `.github/workflows/cargo-deny.yml`). Referência canônica: [`docs/development/release-checklist.md`](docs/development/release-checklist.md). diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..f2a45bb --- /dev/null +++ b/deny.toml @@ -0,0 +1,54 @@ +# Configuração para `cargo-deny` (https://crates.io/crates/cargo-deny). +# +# Verifica licenças, advisories de segurança, fontes confiáveis e bans de deps. +# Rodar: cargo deny check +# CI: .github/workflows/cargo-deny.yml + +[graph] +all-features = true +no-default-features = false + +[advisories] +version = 2 +# Falha em advisories abertas no rustsec.org. Sem ignores; quando uma advisory +# aparecer, abrimos issue para tratar antes de mergear. +yanked = "deny" +ignore = [] + +[licenses] +version = 2 +# Allowlist baseada em SPDX. Restritivo de propósito — uma license nova só +# entra com PR explícito justificando. +allow = [ + "MIT", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "Unicode-DFS-2016", + "Unicode-3.0", + "CC0-1.0", + "Zlib", + "MPL-2.0", # weak copyleft, compatível com Apache/MIT + "0BSD", +] +# License que não constam no SPDX mas são triviais para crates comuns. +exceptions = [] +# Crates com declaração ambígua mas conhecidas como OK. Vazio por agora. +private = { ignore = true } + +[bans] +multiple-versions = "warn" +wildcards = "deny" +highlight = "all" +# Permitir versões duplicadas comuns no ecossistema (futures, syn, etc.) sem +# encher de noise. Cada novo allow exige justificativa em PR. +skip = [] +skip-tree = [] + +[sources] +unknown-registry = "deny" +unknown-git = "deny" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] diff --git a/docs/development/release-checklist.md b/docs/development/release-checklist.md index 264dd48..0cce0d7 100644 --- a/docs/development/release-checklist.md +++ b/docs/development/release-checklist.md @@ -2,6 +2,8 @@ Checklist obrigatório para toda release. Referência canônica linkada em CLAUDE.md. +A partir de v0.4: **per-crate independent versioning** (estilo tokio/axum). Cada crate ganha tag próprio `-vX.Y.Z`. Pré-v0.4 usava workspace-wide unified versioning. + --- ## Antes do Release @@ -10,19 +12,28 @@ Checklist obrigatório para toda release. Referência canônica linkada em CLAUD - [ ] `cargo test -p serverust-core` passa - [ ] `cargo test -p serverust-macros` passa - [ ] `cargo test -p serverust-telemetry` passa -- [ ] `cargo test -p serverust-events` passa +- [ ] `cargo test -p serverust-events` passa (com features `sqs in-memory` para cobertura completa) - [ ] `cargo test -p serverust-lambda` passa - [ ] `scripts/quality_fmt.sh` passa - [ ] `scripts/quality_lint.sh` passa - [ ] `scripts/quality_complexity.sh` passa - [ ] `scripts/quality_cycles.sh` passa - [ ] `scripts/quality_changelog.sh` passa (versão em Cargo.toml tem entrada em CHANGELOG.md) -- [ ] `scripts/quality_hello_world.sh` passa (hello-world sem deps Kafka/DynamoDB) +- [ ] `scripts/quality_hello_world.sh` passa (hello-world sem deps Kafka/DynamoDB/SQS) +- [ ] `cargo deny check` passa (CI: `.github/workflows/cargo-deny.yml`) ## Versão e Changelog -- [ ] Incrementar `version` em `Cargo.toml` workspace -- [ ] Mover itens de `[Unreleased]` para nova versão com data em CHANGELOG.md +### Decisão: workspace-wide vs per-crate + +- **Per-crate** (default a partir de v0.4): bump apenas o(s) crate(s) que mudaram. Tag `serverust-events-v0.3.1`. +- **Workspace-wide** (legado v0.1.x..v0.3.x): bump `workspace.package.version` em `Cargo.toml`. Tag `v0.3.0`. + +### Etapas + +- [ ] Incrementar `version` no(s) `Cargo.toml` do(s) crate(s) afetado(s) +- [ ] Atualizar refs path-deps internas para a nova versão (ex: `serverust-events` depende de `serverust-telemetry = "X.Y.Z"`) +- [ ] Mover itens de `[Unreleased]` para nova versão com data em `CHANGELOG.md` - [ ] `scripts/quality_changelog.sh` verde ## Benchmarks e Métricas @@ -42,19 +53,76 @@ Checklist obrigatório para toda release. Referência canônica linkada em CLAUD - [ ] Versões de Rocket/Loco/actix-web/axum re-validadas nas releases oficiais - [ ] Tabela comparativa do README atualizada se necessário -- [ ] `docs/product/competitors/rocket.md`, `loco.md`, `actix.md` com seção "Kafka & Event Sources" atualizada +- [ ] `docs/product/competitors/rocket.md`, `loco.md`, `actix.md` com seção atualizada ## Publicação -- [ ] Tag git criada: `git tag -s v -m "Release v"` -- [ ] Publicar crates na ordem: - 1. `cargo publish -p serverust-macros` - 2. `cargo publish -p serverust-core` - 3. `cargo publish -p serverust-telemetry` - 4. `cargo publish -p serverust-lambda` - 5. `cargo publish -p serverust-events` - 6. `cargo publish -p serverust-cli` -- [ ] CI passou com a tag (verificar GitHub Actions) +### Opção A — `cargo-release` (recomendado, atômico) + +`cargo-release` é o wrapper que tokio e maintainers Rust top usam. Configurado em `release.toml`. + +```bash +# Instalar uma vez: +cargo install cargo-release + +# Patch release de um crate específico: +cargo release patch -p serverust-events --execute + +# Workspace inteiro (bump major/minor/patch em tudo que mudou): +cargo release patch --workspace --execute + +# Dry-run (default, sem --execute): +cargo release patch --workspace +``` + +`cargo-release` faz tudo em uma corrida: bump → CHANGELOG date → commit → tag SSH-signed (`-v`) → push → `cargo publish` na ordem certa. + +### Opção B — `cargo publish --workspace` (Cargo 1.90+) + +A partir de Cargo 1.90 (Nov 2025) o `cargo publish` aceita `--workspace` e resolve ordem de dependência sozinho: + +```bash +cargo publish --workspace # publica TODOS os crates do workspace +cargo publish -p serverust-macros -p serverust-core # subset selecionado +``` + +Diferença vs Opção A: não faz bump/tag, só publica. Pré-requisito: versões já bumpadas e commit feito. + +### Opção C — Manual sequencial (legado v0.3.x) + +```bash +git tag -s v -m "Release v" + +cargo publish -p serverust-macros +cargo publish -p serverust-core +cargo publish -p serverust-telemetry +cargo publish -p serverust-events +cargo publish -p serverust-lambda +cargo publish -p serverust-cli + +git push origin v +``` + +### Depois do publish + +- [ ] CI passou **com a tag** (`git push origin ` dispara workflow no commit do tag) +- [ ] Verificar página do crate em https://crates.io/crates/ +- [ ] Documentação publicada em https://docs.rs/ (geração automática ~10 min) +- [ ] Anúncio de release em GitHub Releases (opcional, `gh release create`) + +--- + +## Pré-flight obrigatório (Cargo + assinatura) + +- Cargo 1.90+ (para `cargo publish --workspace`). Verificar: `cargo --version`. +- SSH signing configurado para tags assinados: + ```bash + git config --global gpg.format ssh + git config --global user.signingkey ~/.ssh/id_.pub + git config --global tag.gpgsign true + ``` +- Public key adicionada como **Signing key** em https://github.com/settings/ssh/new (diferente de Authentication key). +- `cargo login` configurado (token em `~/.cargo/credentials.toml`). --- diff --git a/release.toml b/release.toml new file mode 100644 index 0000000..d4b5096 --- /dev/null +++ b/release.toml @@ -0,0 +1,46 @@ +# Configuração para `cargo-release` (https://crates.io/crates/cargo-release). +# +# Uso típico: +# cargo release patch --execute # bump patch + tag + publish (todos os crates) +# cargo release minor --execute # bump minor (ex: feature nova) +# cargo release major --execute # bump major (ex: breaking change) +# cargo release version --execute # bump específico +# +# Dry-run (default sem --execute): +# cargo release patch # mostra o que faria +# +# Per-crate (estilo tokio/axum): +# cargo release patch -p serverust-events --execute + +# ─── Comportamento global ────────────────────────────────────────────── +sign-commit = false +sign-tag = true +push = true +publish = true +verify = true + +# Política do tag por crate (estilo tokio/axum): `-vX.Y.Z`. +# Ex: `serverust-events-v0.3.1`, `serverust-cli-v0.4.0`. +# Quando rodar `cargo release --workspace`, um tag por crate alterado. +tag-name = "{{crate_name}}-v{{version}}" +tag-message = "Release {{crate_name}} v{{version}}" + +# Mensagem do commit de release. +pre-release-commit-message = "chore(release): {{crate_name}} v{{version}}" + +# Branch alvo. Sem allow-branch = só permite na branch atual; explicitar `main` +# evita release acidental em branch de feature. +allow-branch = ["main", "release/*"] + +# Bloqueia release com working tree sujo (default true; explícito por seguran ̧ça). +dependent-version = "upgrade" + +# ─── Hooks ──────────────────────────────────────────────────────────── +# Antes do publish, valida changelog e métricas obrigatórias. +pre-release-hook = ["scripts/quality_changelog.sh"] + +# ─── Substituições no CHANGELOG ────────────────────────────────────── +# Atualiza placeholders {{date}} e {{version}} se usados em CHANGELOG.md. +pre-release-replacements = [ + { file = "CHANGELOG.md", search = "## \\[Unreleased\\]", replace = "## [Unreleased]\n\n## [{{version}}] - {{date}}", exactly = 1 }, +] From 2f47f47c41f585fa277fc6224690dba39ae11974 Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Sun, 17 May 2026 19:38:45 -0300 Subject: [PATCH 3/9] feat(ci): release-plz + cocogitto + cargo-nextest + cargo-machete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Substitui cargo-release (do commit anterior) pelo stack Rust-native completo: **release-plz** (substitui cargo-release): - release-plz.toml — workspace publishing (per-crate tags, cargo-semver-checks, git-cliff CHANGELOG, GitHub Releases automáticos) - cliff.toml — template git-cliff para CHANGELOG estilo Keep a Changelog - .github/workflows/release-plz.yml — CI dispara em push main + workflow_dispatch: abre Release PR (release-pr command) e dispara publish ao merge (release command) - Remove release.toml (cargo-release config) — release-plz cobre tudo **cocogitto** (Conventional Commits Rust-native): - cog.toml — config com tipos permitidos + branch whitelist - .github/workflows/commitlint.yml — cog check em PR (commits da PR) e push main (desde último tag) - lefthook commit-msg hook chama `cog verify` localmente (skip se ausente) **cargo-nextest** (testes mais rápidos): - .github/workflows/tests.yml — matrix por crate+features rodando nextest run. Cobre serverust-events com feature combos críticos (sqs, kafka, asyncapi). Respeita CLAUDE.md (nunca workspace inteiro de uma vez). **cargo-machete** (deps não-usadas): - .github/workflows/cargo-machete.yml — PR + cron semanal segunda 06:17 UTC - lefthook pre-commit chama `cargo machete` localmente (skip se ausente) **Docs:** - CLAUDE.md § Processo de Release reescrito (Opção A = release-plz CI-driven) - docs/development/release-checklist.md — Opção A release-plz, Opção B cargo publish --workspace, Opção C manual legado Pré-flight: GitHub secret CARGO_REGISTRY_TOKEN no env Teste para release-plz. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/cargo-machete.yml | 20 +++++++ .github/workflows/commitlint.yml | 34 +++++++++++ .github/workflows/release-plz.yml | 51 ++++++++++++++++ .github/workflows/tests.yml | 62 ++++++++++++++++++++ CLAUDE.md | 22 ++++--- cliff.toml | 57 ++++++++++++++++++ cog.toml | 42 ++++++++++++++ docs/development/release-checklist.md | 30 +++++----- lefthook.yml | 12 ++++ release-plz.toml | 83 +++++++++++++++++++++++++++ release.toml | 46 --------------- 11 files changed, 388 insertions(+), 71 deletions(-) create mode 100644 .github/workflows/cargo-machete.yml create mode 100644 .github/workflows/commitlint.yml create mode 100644 .github/workflows/release-plz.yml create mode 100644 .github/workflows/tests.yml create mode 100644 cliff.toml create mode 100644 cog.toml create mode 100644 release-plz.toml delete mode 100644 release.toml diff --git a/.github/workflows/cargo-machete.yml b/.github/workflows/cargo-machete.yml new file mode 100644 index 0000000..27d4317 --- /dev/null +++ b/.github/workflows/cargo-machete.yml @@ -0,0 +1,20 @@ +name: cargo-machete + +on: + pull_request: + paths: + - "**/Cargo.toml" + - "**/Cargo.lock" + - "**/*.rs" + - ".github/workflows/cargo-machete.yml" + schedule: + # Cron semanal para pegar deps removidas/órfãs no ecossistema. + - cron: "17 6 * * 1" + +jobs: + machete: + name: Find unused dependencies + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: bnjbvr/cargo-machete@main diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000..2b110a6 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,34 @@ +name: commitlint + +on: + pull_request: + types: [opened, edited, reopened, synchronize] + push: + branches: [main] + +permissions: + contents: read + +jobs: + cog-check: + name: Conventional Commits (cocogitto) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # cog precisa histórico completo + - name: Install cocogitto + run: | + curl -L --proto '=https' --tlsv1.2 -sSf \ + https://raw.githubusercontent.com/cocogitto/cocogitto/main/install.sh | bash + echo "$HOME/.cocogitto/bin" >> "$GITHUB_PATH" + - name: Validate commit history + # Em PR: valida só os commits da PR (from-latest-tag = false). + # Em push para main: cog check valida tudo desde o último tag. + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + git fetch origin ${{ github.base_ref }} + cog check origin/${{ github.base_ref }}..HEAD + else + cog check + fi diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml new file mode 100644 index 0000000..19b69d9 --- /dev/null +++ b/.github/workflows/release-plz.yml @@ -0,0 +1,51 @@ +name: release-plz + +on: + push: + branches: [main] + # workflow_dispatch permite trigger manual via UI ("Run workflow") — útil + # para forçar release após hot-fix. + workflow_dispatch: + +permissions: + pull-requests: write + contents: write + +jobs: + release-plz-release: + name: release-plz / release + runs-on: ubuntu-latest + if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + - uses: dtolnay/rust-toolchain@stable + - uses: release-plz/action@v0.5 + with: + command: release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + + release-plz-pr: + name: release-plz / release-pr + runs-on: ubuntu-latest + if: github.event_name == 'push' + concurrency: + # Cancela release-pr anterior se um novo push chegar — evita PRs duplicados. + group: release-plz-${{ github.ref }} + cancel-in-progress: false + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + - uses: dtolnay/rust-toolchain@stable + - uses: release-plz/action@v0.5 + with: + command: release-pr + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..9be1b61 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,62 @@ +name: tests + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + nextest: + name: cargo nextest (${{ matrix.crate }} / features=${{ matrix.features }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + # Rodamos por crate para isolar falhas e respeitar a regra "nunca workspace + # build inteiro de uma vez" (CLAUDE.md). nextest é mais rápido por design + # (parallelism + retry). + matrix: + include: + - crate: serverust-macros + features: "" + - crate: serverust-core + features: "" + - crate: serverust-telemetry + features: "" + - crate: serverust-telemetry + features: "in-memory" + - crate: serverust-events + features: "" + - crate: serverust-events + features: "sqs in-memory" + - crate: serverust-events + features: "kafka" + - crate: serverust-events + features: "asyncapi sqs" + - crate: serverust-lambda + features: "" + - crate: serverust-cli + features: "" + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + # Cache key inclui matrix para isolar caches por crate+features. + shared-key: "tests-${{ matrix.crate }}-${{ matrix.features }}" + - name: Install librdkafka build deps (kafka feature) + if: contains(matrix.features, 'kafka') + run: sudo apt-get update && sudo apt-get install -y cmake build-essential libssl-dev libsasl2-dev + - name: Install cargo-nextest + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest + - name: Run tests + run: | + if [ -z "${{ matrix.features }}" ]; then + cargo nextest run -p ${{ matrix.crate }} + else + cargo nextest run -p ${{ matrix.crate }} --features "${{ matrix.features }}" + fi diff --git a/CLAUDE.md b/CLAUDE.md index f509bde..2469428 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,17 +26,23 @@ Estas propriedades são compromissos públicos. Violá-las exige uma nova ADR ap A partir de v0.4: **per-crate independent versioning** (estilo tokio/axum). Tag por crate `-vX.Y.Z`. Pré-v0.4 usava workspace-wide unified versioning. -### Fluxo recomendado (cargo-release) +### Fluxo recomendado (release-plz, automatizado via CI) -```bash -# Patch release de um crate específico: -cargo release patch -p serverust-events --execute +[`release-plz`](https://release-plz.dev) é Rust-native, dispara automaticamente: -# Workspace inteiro (bump + tag + publish na ordem certa, tudo atômico): -cargo release patch --workspace --execute -``` +1. Merge commits seguindo Conventional Commits (`feat:`, `fix:`, `chore:`) no `main`. +2. release-plz abre Release PR com bump per-crate + CHANGELOG via git-cliff + cargo-semver-checks. +3. Merge do Release PR → `cargo publish` (ordem certa) + git tags `-v` + GitHub Release. + +Configs: +- `release-plz.toml` — quais crates publicar, política de tags. +- `cliff.toml` — template CHANGELOG. +- `cog.toml` — Conventional Commits via cocogitto. +- `.github/workflows/release-plz.yml` — CI workflow. + +Pré-flight: secret `CARGO_REGISTRY_TOKEN` (gere em https://crates.io/me). -`cargo-release` (config em `release.toml`) faz: bump → CHANGELOG date → commit → tag SSH-signed → push → `cargo publish` na ordem de dependência. +Trigger manual: Actions → release-plz → "Run workflow". ### Fluxo manual (alternativa) diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..cf41896 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,57 @@ +# Configuração do git-cliff (https://git-cliff.org). +# +# Usado pelo release-plz para gerar CHANGELOG.md a partir de Conventional Commits. +# Também pode ser rodado standalone: `git cliff -o CHANGELOG.md` + +[changelog] +header = """ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +""" +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [Unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {% if commit.breaking %}[**BREAKING**] {% endif %}{{ commit.message | upper_first }} ({{ commit.id | truncate(length=7, end="") }})\ + {% endfor %} +{% endfor %} +""" +trim = true +footer = """ +[unreleased]: https://github.com/JaimeJunr/serverust/compare/{previous}...HEAD +""" + +[git] +conventional_commits = true +filter_unconventional = true +split_commits = false +commit_parsers = [ + { message = "^feat", group = "Added" }, + { message = "^fix", group = "Fixed" }, + { message = "^perf", group = "Performance" }, + { message = "^doc", group = "Documentation" }, + { message = "^refactor", group = "Refactor" }, + { message = "^test", group = "Tests" }, + { message = "^build", group = "Build" }, + { message = "^ci", group = "CI" }, + { message = "^chore\\(release\\)", skip = true }, + { message = "^chore", group = "Chore" }, + { message = "^revert", group = "Revert" }, +] +protect_breaking_commits = true +filter_commits = false +tag_pattern = "^[a-z-]+-v[0-9]+\\.[0-9]+\\.[0-9]+$" +skip_tags = "v0.1.0|v0.2.0" # tags legadas pré-per-crate +ignore_tags = "" +topo_order = false +sort_commits = "newest" diff --git a/cog.toml b/cog.toml new file mode 100644 index 0000000..8247dbb --- /dev/null +++ b/cog.toml @@ -0,0 +1,42 @@ +# Configuração do cocogitto (https://docs.cocogitto.io). +# +# cocogitto é o linter de Conventional Commits Rust-native. +# Usado pelo lefthook (commit-msg hook) e pelo CI (.github/workflows/commitlint.yml). +# +# Validar histórico: cog check +# Validar próximo commit message: cog verify "feat(scope): message" + +# Tipos permitidos (Conventional Commits v1.0 + Angular convention). +[commit_types] +feat = { changelog_title = "Features" } +fix = { changelog_title = "Bug Fixes" } +perf = { changelog_title = "Performance" } +refactor = { changelog_title = "Refactoring" } +docs = { changelog_title = "Documentation" } +test = { changelog_title = "Tests" } +build = { changelog_title = "Build System" } +ci = { changelog_title = "Continuous Integration" } +chore = { changelog_title = "Chores" } +revert = { changelog_title = "Reverts" } +style = { changelog_title = "Style" } + +# Scopes recomendados (monorepo). cog verify warns se scope desconhecido. +# Lista vazia = qualquer scope aceito; descomente para enforcement estrito futuro. +# scopes = ["core", "macros", "events", "telemetry", "lambda", "cli", "examples", "docs", "ci"] + +# Política do tag — bate com release-plz. +tag_prefix = "" +post_bump_hooks = [] + +# Branch base. cog check valida histórico contra a branch atual. +branch_whitelist = ["main", "release-plz/*", "ralph/*", "ci/*", "chore/*", "fix/*", "feat/*", "docs/*"] + +# Permite merge commits e revert commits sem enforcement estrito. +ignore_merge_commits = true + +[changelog] +authors = [] +template = "remote" +remote = "github.com" +repository = "serverust" +owner = "JaimeJunr" diff --git a/docs/development/release-checklist.md b/docs/development/release-checklist.md index 0cce0d7..410e12a 100644 --- a/docs/development/release-checklist.md +++ b/docs/development/release-checklist.md @@ -57,27 +57,23 @@ A partir de v0.4: **per-crate independent versioning** (estilo tokio/axum). Cada ## Publicação -### Opção A — `cargo-release` (recomendado, atômico) +### Opção A — `release-plz` (recomendado, automatizado via CI) -`cargo-release` é o wrapper que tokio e maintainers Rust top usam. Configurado em `release.toml`. +[`release-plz`](https://release-plz.dev) é Rust-native (inspirado pelo Google `release-please` mas otimizado pra Rust). Roda automaticamente em CI: -```bash -# Instalar uma vez: -cargo install cargo-release - -# Patch release de um crate específico: -cargo release patch -p serverust-events --execute +1. **Você merge commits** no `main` seguindo Conventional Commits (`feat:`, `fix:`, `chore:`). +2. **release-plz abre um Release PR** com bump de versão (per-crate, baseado nos commits) + CHANGELOG atualizado via git-cliff + breaking changes detectadas via cargo-semver-checks. +3. **Você mergea o Release PR** → release-plz dispara `cargo publish` (na ordem certa) + cria git tags `-v` + abre GitHub Release. -# Workspace inteiro (bump major/minor/patch em tudo que mudou): -cargo release patch --workspace --execute - -# Dry-run (default, sem --execute): -cargo release patch --workspace -``` +Configuração: +- `release-plz.toml` na raiz — quais crates publicar, política de tags. +- `cliff.toml` na raiz — template do CHANGELOG. +- `.github/workflows/release-plz.yml` — CI workflow. +- Secret `CARGO_REGISTRY_TOKEN` no environment GitHub (gere em https://crates.io/me). -`cargo-release` faz tudo em uma corrida: bump → CHANGELOG date → commit → tag SSH-signed (`-v`) → push → `cargo publish` na ordem certa. +Trigger manual: vá em Actions → release-plz → "Run workflow". -### Opção B — `cargo publish --workspace` (Cargo 1.90+) +### Opção B — `cargo publish --workspace` (manual, Cargo 1.90+) A partir de Cargo 1.90 (Nov 2025) o `cargo publish` aceita `--workspace` e resolve ordem de dependência sozinho: @@ -86,7 +82,7 @@ cargo publish --workspace # publica TODOS os crates do workspace cargo publish -p serverust-macros -p serverust-core # subset selecionado ``` -Diferença vs Opção A: não faz bump/tag, só publica. Pré-requisito: versões já bumpadas e commit feito. +Use quando precisar de publish ad-hoc sem passar por release-plz. Pré-requisito: versões já bumpadas e commit feito. ### Opção C — Manual sequencial (legado v0.3.x) diff --git a/lefthook.yml b/lefthook.yml index 0389ea1..9c6f8af 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -11,6 +11,18 @@ pre-commit: run: ./scripts/quality_cycles.sh hello_world: run: ./scripts/quality_hello_world.sh + machete: + # Detecta deps não-usadas (cargo-machete). Skip silencioso se a tool + # não estiver instalada — sem força instalação compulsória. + run: command -v cargo-machete >/dev/null 2>&1 && cargo machete || echo "[skip] cargo-machete ausente (cargo install cargo-machete)" + +# Valida commit message contra Conventional Commits via cocogitto (cog.toml). +commit-msg: + commands: + cog-verify: + # Skip silencioso se cog não estiver instalado. Instalação: + # curl https://raw.githubusercontent.com/cocogitto/cocogitto/main/install.sh | bash + run: command -v cog >/dev/null 2>&1 && cog verify --file {1} || echo "[skip] cocogitto ausente" pre-push: parallel: false diff --git a/release-plz.toml b/release-plz.toml new file mode 100644 index 0000000..99c0437 --- /dev/null +++ b/release-plz.toml @@ -0,0 +1,83 @@ +# Configuração do release-plz (https://release-plz.dev). +# +# release-plz roda em CI (.github/workflows/release-plz.yml) e: +# 1. Compara local com crates.io para descobrir o que precisa de release +# 2. Abre Release PR com bump de versão + CHANGELOG atualizado + tag annotation +# 3. Quando o Release PR é mergeado, dispara cargo publish + git tag + GitHub Release +# +# Tags geradas: `-v` (per-crate, estilo tokio/axum). +# CHANGELOG: gerado por git-cliff (config em cliff.toml). +# Breaking changes: detectadas por cargo-semver-checks integrado. + +[workspace] +# Conventional Commits opcionais — release-plz usa para bump automático +# (feat = minor, fix = patch, feat!/BREAKING CHANGE = major). +changelog_config = "cliff.toml" + +# Habilita cargo-semver-checks para detectar breaking changes em código que +# o autor marcou como `fix:` sem `!:` — protege contra patch release acidental. +semver_check = true + +# Cria GitHub Releases para cada tag. Body = changelog do crate. +git_release_enable = true +git_release_type = "auto" # prerelease se versão tem -alpha/-beta/-rc + +# Tag pattern por crate — encaixa com release-plz workflow. +git_tag_name = "{{ package }}-v{{ version }}" + +# Comentário no Release PR explicando o que mudou por crate. +pr_branch_prefix = "release-plz/" +pr_labels = ["release"] +pr_name = "chore: release" + +# Atualizações de dependências internas no workspace — bump dependentes quando +# o crate dependente recebe minor/patch (mantém path-deps consistentes). +dependencies_update = true + +# Crates publicáveis. Listados explicitamente para evitar publicar examples/ +# por engano. release-plz só toca o que está listado. +[[package]] +name = "serverust-macros" +publish = true +publish_features = [] + +[[package]] +name = "serverust-core" +publish = true + +[[package]] +name = "serverust-telemetry" +publish = true + +[[package]] +name = "serverust-events" +publish = true + +[[package]] +name = "serverust-lambda" +publish = true + +[[package]] +name = "serverust-cli" +publish = true + +# Crates internas que NÃO devem ser publicadas (examples, baselines). +[[package]] +name = "hello-world" +publish = false +release = false + +[[package]] +name = "funds-api" +publish = false +release = false + +[[package]] +name = "todo-api" +publish = false +release = false + +[[package]] +name = "kafka-wallet" +publish = false +release = false diff --git a/release.toml b/release.toml deleted file mode 100644 index d4b5096..0000000 --- a/release.toml +++ /dev/null @@ -1,46 +0,0 @@ -# Configuração para `cargo-release` (https://crates.io/crates/cargo-release). -# -# Uso típico: -# cargo release patch --execute # bump patch + tag + publish (todos os crates) -# cargo release minor --execute # bump minor (ex: feature nova) -# cargo release major --execute # bump major (ex: breaking change) -# cargo release version --execute # bump específico -# -# Dry-run (default sem --execute): -# cargo release patch # mostra o que faria -# -# Per-crate (estilo tokio/axum): -# cargo release patch -p serverust-events --execute - -# ─── Comportamento global ────────────────────────────────────────────── -sign-commit = false -sign-tag = true -push = true -publish = true -verify = true - -# Política do tag por crate (estilo tokio/axum): `-vX.Y.Z`. -# Ex: `serverust-events-v0.3.1`, `serverust-cli-v0.4.0`. -# Quando rodar `cargo release --workspace`, um tag por crate alterado. -tag-name = "{{crate_name}}-v{{version}}" -tag-message = "Release {{crate_name}} v{{version}}" - -# Mensagem do commit de release. -pre-release-commit-message = "chore(release): {{crate_name}} v{{version}}" - -# Branch alvo. Sem allow-branch = só permite na branch atual; explicitar `main` -# evita release acidental em branch de feature. -allow-branch = ["main", "release/*"] - -# Bloqueia release com working tree sujo (default true; explícito por seguran ̧ça). -dependent-version = "upgrade" - -# ─── Hooks ──────────────────────────────────────────────────────────── -# Antes do publish, valida changelog e métricas obrigatórias. -pre-release-hook = ["scripts/quality_changelog.sh"] - -# ─── Substituições no CHANGELOG ────────────────────────────────────── -# Atualiza placeholders {{date}} e {{version}} se usados em CHANGELOG.md. -pre-release-replacements = [ - { file = "CHANGELOG.md", search = "## \\[Unreleased\\]", replace = "## [Unreleased]\n\n## [{{version}}] - {{date}}", exactly = 1 }, -] From 57fef94b26f12a5ce980ebfaee837ce9634d1ef7 Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Mon, 18 May 2026 11:19:23 -0300 Subject: [PATCH 4/9] =?UTF-8?q?fix(ci):=20endere=C3=A7a=205=20fails=20do?= =?UTF-8?q?=20pipeline=20release-plz/tooling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviews automáticos do PR #9 identificaram falhas nos checks novos: 1. **cocogitto install 404**: install.sh do upstream retornou 404. Trocado por taiki-e/install-action que pega binary release oficial direto do GitHub. 2. **cargo-machete false positives**: deps usadas via macro/feature flag não rastreadas pelo machete. Adicionado `[package.metadata.cargo-machete]` ignored em: - serverust-events: aws-config, pin-project-lite - serverust-telemetry: aws-config, tracing-opentelemetry - examples/baselines/axum-raw-kafka: rdkafka-sys, thiserror 3. **cargo-deny unlicensed**: examples sem license declarada. Adicionado `publish = false` em hello-world, funds-api, todo-api — combina com `private.ignore = true` no deny.toml (kafka-wallet e axum-raw-kafka já tinham). 4. **nextest events kafka libcurl missing**: rdkafka-sys 4.10+ requer curl/curl.h. Adicionado libcurl4-openssl-dev ao apt install do step. 5. **nextest telemetry in-memory**: serverust-telemetry não tem feature `in-memory`. Removido da matrix (foi engano meu no commit anterior). Gate local cargo check --workspace verde. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/commitlint.yml | 9 +++++---- .github/workflows/tests.yml | 5 ++--- examples/baselines/axum-raw-kafka/Cargo.toml | 5 +++++ examples/funds-api/Cargo.toml | 1 + examples/hello-world/Cargo.toml | 1 + examples/todo-api/Cargo.toml | 1 + serverust-events/Cargo.toml | 5 +++++ serverust-telemetry/Cargo.toml | 5 +++++ 8 files changed, 25 insertions(+), 7 deletions(-) diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 2b110a6..0eb270d 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -18,10 +18,11 @@ jobs: with: fetch-depth: 0 # cog precisa histórico completo - name: Install cocogitto - run: | - curl -L --proto '=https' --tlsv1.2 -sSf \ - https://raw.githubusercontent.com/cocogitto/cocogitto/main/install.sh | bash - echo "$HOME/.cocogitto/bin" >> "$GITHUB_PATH" + # cargo-binstall pega binary release oficial direto do GitHub releases. + # Mais confiável que install.sh (que retornou 404 em 2026-05). + uses: taiki-e/install-action@v2 + with: + tool: cocogitto - name: Validate commit history # Em PR: valida só os commits da PR (from-latest-tag = false). # Em push para main: cog check valida tudo desde o último tag. diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9be1b61..7948798 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,8 +25,6 @@ jobs: features: "" - crate: serverust-telemetry features: "" - - crate: serverust-telemetry - features: "in-memory" - crate: serverust-events features: "" - crate: serverust-events @@ -48,7 +46,8 @@ jobs: shared-key: "tests-${{ matrix.crate }}-${{ matrix.features }}" - name: Install librdkafka build deps (kafka feature) if: contains(matrix.features, 'kafka') - run: sudo apt-get update && sudo apt-get install -y cmake build-essential libssl-dev libsasl2-dev + # libcurl4-openssl-dev: rdkafka-sys >=4.10 requer curl/curl.h em build. + run: sudo apt-get update && sudo apt-get install -y cmake build-essential libssl-dev libsasl2-dev libcurl4-openssl-dev - name: Install cargo-nextest uses: taiki-e/install-action@v2 with: diff --git a/examples/baselines/axum-raw-kafka/Cargo.toml b/examples/baselines/axum-raw-kafka/Cargo.toml index 8b038bb..6fb5f8a 100644 --- a/examples/baselines/axum-raw-kafka/Cargo.toml +++ b/examples/baselines/axum-raw-kafka/Cargo.toml @@ -26,3 +26,8 @@ serde_json = "1" base64 = "0.22" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } thiserror = "1" + +# cargo-machete false positives: rdkafka-sys é peer-dep pinned do rdkafka; +# thiserror é usado via #[derive(Error)] que machete não rastreia. +[package.metadata.cargo-machete] +ignored = ["rdkafka-sys", "thiserror"] diff --git a/examples/funds-api/Cargo.toml b/examples/funds-api/Cargo.toml index fa46f69..a3f1fc5 100644 --- a/examples/funds-api/Cargo.toml +++ b/examples/funds-api/Cargo.toml @@ -3,6 +3,7 @@ name = "funds-api" version = "0.1.0" edition = "2024" rust-version = "1.85" +publish = false [[bin]] name = "funds-api" diff --git a/examples/hello-world/Cargo.toml b/examples/hello-world/Cargo.toml index 7fbfdbc..2101194 100644 --- a/examples/hello-world/Cargo.toml +++ b/examples/hello-world/Cargo.toml @@ -3,6 +3,7 @@ name = "hello-world" version = "0.1.0" edition = "2024" rust-version = "1.85" +publish = false [[bin]] name = "hello-world" diff --git a/examples/todo-api/Cargo.toml b/examples/todo-api/Cargo.toml index 69cd90a..8322738 100644 --- a/examples/todo-api/Cargo.toml +++ b/examples/todo-api/Cargo.toml @@ -3,6 +3,7 @@ name = "todo-api" version = "0.1.0" edition = "2024" rust-version = "1.85" +publish = false [[bin]] name = "todo-api" diff --git a/serverust-events/Cargo.toml b/serverust-events/Cargo.toml index 8b58ceb..ea2a649 100644 --- a/serverust-events/Cargo.toml +++ b/serverust-events/Cargo.toml @@ -150,3 +150,8 @@ required-features = ["sqs"] [[test]] name = "sqs_observability" required-features = ["sqs"] + +# cargo-machete false positives: aws-config é ativado por features que machete +# não enumera; pin-project-lite é usado em codegen das macros Tower. +[package.metadata.cargo-machete] +ignored = ["aws-config", "pin-project-lite"] diff --git a/serverust-telemetry/Cargo.toml b/serverust-telemetry/Cargo.toml index 34b4e69..c988554 100644 --- a/serverust-telemetry/Cargo.toml +++ b/serverust-telemetry/Cargo.toml @@ -54,3 +54,8 @@ dynamodb = ["dep:aws-sdk-dynamodb", "dep:aws-config"] tokio = { version = "1", features = ["macros", "rt-multi-thread"] } tower = { version = "0.5", features = ["util"] } serverust-macros = { path = "../serverust-macros", version = "0.3.0" } + +# cargo-machete false positives: aws-config e tracing-opentelemetry são ativados +# por features (otel/dynamodb) que machete não enumera por padrão. +[package.metadata.cargo-machete] +ignored = ["aws-config", "tracing-opentelemetry"] From 89455dd95e6a677d5607b1bbcc325a7a36d9448e Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Mon, 18 May 2026 11:20:58 -0300 Subject: [PATCH 5/9] =?UTF-8?q?fix(ci):=20reorder=20cog.toml=20=E2=80=94?= =?UTF-8?q?=20global=20keys=20before=20[commit=5Ftypes]=20table?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TOML parser was nesting branch_whitelist under [commit_types] table due to key ordering. Cocogitto erro: 'expected boolean for branch_whitelist[1]'. Fix: move tag_prefix, ignore_merge_commits, branch_whitelist, post_bump_hooks para antes da primeira [table]. --- cog.toml | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/cog.toml b/cog.toml index 8247dbb..b7d27c9 100644 --- a/cog.toml +++ b/cog.toml @@ -6,7 +6,26 @@ # Validar histórico: cog check # Validar próximo commit message: cog verify "feat(scope): message" -# Tipos permitidos (Conventional Commits v1.0 + Angular convention). +# ─── Chaves globais (devem vir ANTES de qualquer [table]) ────────────────── + +# Política do tag — bate com release-plz. +tag_prefix = "" + +# Permite merge commits e revert commits sem enforcement estrito. +ignore_merge_commits = true + +# Branch base. cog check valida histórico contra a branch atual. +branch_whitelist = ["main", "release-plz/*", "ralph/*", "ci/*", "chore/*", "fix/*", "feat/*", "docs/*"] + +# Hooks pós-bump (vazio = sem hooks customizados). +post_bump_hooks = [] + +# Scopes recomendados (monorepo). Lista vazia = qualquer scope aceito; +# descomente para enforcement estrito. +# scopes = ["core", "macros", "events", "telemetry", "lambda", "cli", "examples", "docs", "ci"] + +# ─── Tipos de commit ─────────────────────────────────────────────────────── +# Conventional Commits v1.0 + Angular convention. [commit_types] feat = { changelog_title = "Features" } fix = { changelog_title = "Bug Fixes" } @@ -20,20 +39,7 @@ chore = { changelog_title = "Chores" } revert = { changelog_title = "Reverts" } style = { changelog_title = "Style" } -# Scopes recomendados (monorepo). cog verify warns se scope desconhecido. -# Lista vazia = qualquer scope aceito; descomente para enforcement estrito futuro. -# scopes = ["core", "macros", "events", "telemetry", "lambda", "cli", "examples", "docs", "ci"] - -# Política do tag — bate com release-plz. -tag_prefix = "" -post_bump_hooks = [] - -# Branch base. cog check valida histórico contra a branch atual. -branch_whitelist = ["main", "release-plz/*", "ralph/*", "ci/*", "chore/*", "fix/*", "feat/*", "docs/*"] - -# Permite merge commits e revert commits sem enforcement estrito. -ignore_merge_commits = true - +# ─── Changelog (usado pelo `cog changelog`) ──────────────────────────────── [changelog] authors = [] template = "remote" From e786b98c6fb664c0ed0407e7f992306cd2a24c70 Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Mon, 18 May 2026 11:26:32 -0300 Subject: [PATCH 6/9] fix(ci): allow-wildcard-paths para examples publish=false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cargo-deny bans.wildcards trata path-deps sem version como erro. Examples internos (hello-world, funds-api, todo-api, kafka-wallet) usam path-only para serverust-* deps. Como publish=false, é seguro: opt-in allow-wildcard-paths = true mantém o check ativo para crates publicáveis. --- deny.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deny.toml b/deny.toml index f2a45bb..b2fce29 100644 --- a/deny.toml +++ b/deny.toml @@ -41,6 +41,9 @@ private = { ignore = true } [bans] multiple-versions = "warn" wildcards = "deny" +# Path-deps em crates `publish = false` (examples internos) são tratadas como +# wildcards pelo cargo-deny. Como os examples nunca vão pra crates.io, opt-in: +allow-wildcard-paths = true highlight = "all" # Permitir versões duplicadas comuns no ecossistema (futures, syn, etc.) sem # encher de noise. Cada novo allow exige justificativa em PR. From 08947ecfebaa6d93cfddfa4ca53b1ae81d624b5c Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Mon, 18 May 2026 11:35:07 -0300 Subject: [PATCH 7/9] fix(ci): ignore 3 RUSTSEC advisories em rustls-webpki 0.101.7 transitive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cargo-deny falhava em: - RUSTSEC-2026-0098: name constraints for URI names incorretas - RUSTSEC-2026-0099: wildcard name em name constraints - RUSTSEC-2026-0104: reachable panic em CRL parsing Todas em rustls-webpki 0.101.7, pinned indiretamente via: aws-config -> aws-smithy-http-client -> rustls 0.21 -> rustls-webpki 0.101.7 Impacto real baixo: TLS para AWS endpoints com CA chain controlada (AWS Trust Services), não user-supplied. Não há upgrade direto possível enquanto aws-sdk-rust não migrar para rustls 0.23+. Roadmap entry adicionada para tracking de quando remover os ignores. --- deny.toml | 17 ++++++++++++++--- docs/product/roadmap.md | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/deny.toml b/deny.toml index b2fce29..ad1adcb 100644 --- a/deny.toml +++ b/deny.toml @@ -10,10 +10,21 @@ no-default-features = false [advisories] version = 2 -# Falha em advisories abertas no rustsec.org. Sem ignores; quando uma advisory -# aparecer, abrimos issue para tratar antes de mergear. +# Falha em advisories abertas no rustsec.org. yanked = "deny" -ignore = [] +# Ignores com justificativa explícita. Cada entrada deve ter comentário sobre +# (a) por que não dá pra atualizar, (b) qual o impacto real no contexto, +# (c) quando podemos remover. +ignore = [ + # rustls-webpki 0.101.7 (transitive via aws-smithy-http-client → AWS SDK). + # Impacto: TLS para AWS endpoints (DynamoDB, SQS, etc.). Risco real baixo + # porque a CA chain é a AWS Trust Services (controlada), não user-supplied. + # Remover quando aws-sdk-rust subir para rustls 0.23 (acompanhar + # https://github.com/awslabs/aws-sdk-rust/issues — atualmente pin 0.21). + "RUSTSEC-2026-0098", # name constraints for URI names incorretas + "RUSTSEC-2026-0099", # wildcard name em name constraints + "RUSTSEC-2026-0104", # reachable panic em CRL parsing +] [licenses] version = 2 diff --git a/docs/product/roadmap.md b/docs/product/roadmap.md index 3c1efc7..e1910b9 100644 --- a/docs/product/roadmap.md +++ b/docs/product/roadmap.md @@ -100,6 +100,7 @@ Inspiração: SST, AWS SAM, Encore.ts, Cargo Lambda. Pesquisa em `docs/research/ - gRPC via tonic adapter - Suporte a outros brokers: RabbitMQ (`serverust-rabbitmq`), NATS (`serverust-nats`) — `Broker` trait já está pronta - Suporte a outros providers serverless (GCP Cloud Run, Azure Functions) +- **Remover ignores de RUSTSEC em `deny.toml`** quando `aws-sdk-rust` subir para `rustls 0.23+`: RUSTSEC-2026-0098, 0099, 0104 (rustls-webpki 0.101.7 transitive via aws-smithy-http-client). Acompanhar https://github.com/awslabs/aws-sdk-rust/issues. --- From f6bfd1857290efb3d16ad7fea3990b49a095f216 Mon Sep 17 00:00:00 2001 From: jaimejunr Date: Wed, 27 May 2026 13:35:11 -0300 Subject: [PATCH 8/9] =?UTF-8?q?chore(dev):=20otimiza=20profile.dev=20?= =?UTF-8?q?=E2=80=94=20line-tables-only=20+=20split-debuginfo=20unpacked?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acelera compilação incremental local desligando debug info de deps externas e usando split-debuginfo unpacked no crate atual. Co-Authored-By: Claude Opus 4.7 --- Cargo.toml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index aa6c1eb..a0db3ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,10 @@ documentation = "https://docs.rs/serverust-core" readme = "README.md" keywords = ["lambda", "serverless", "aws", "framework", "api"] categories = ["web-programming", "web-programming::http-server", "asynchronous"] + +[profile.dev] +debug = "line-tables-only" +split-debuginfo = "unpacked" + +[profile.dev.package."*"] +debug = false From 25afcf80cb2db165bf8f5727fa488bd12c1d2589 Mon Sep 17 00:00:00 2001 From: Jaime Basso <138415231+JaimeJunr@users.noreply.github.com> Date: Wed, 27 May 2026 22:17:21 -0300 Subject: [PATCH 9/9] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- cliff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cliff.toml b/cliff.toml index cf41896..6caebc2 100644 --- a/cliff.toml +++ b/cliff.toml @@ -28,7 +28,7 @@ body = """ """ trim = true footer = """ -[unreleased]: https://github.com/JaimeJunr/serverust/compare/{previous}...HEAD +[unreleased]: https://github.com/JaimeJunr/serverust/compare/{{ previous.version }}...HEAD """ [git]