Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/cargo-deny.yml
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions .github/workflows/cargo-machete.yml
Original file line number Diff line number Diff line change
@@ -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
35 changes: 35 additions & 0 deletions .github/workflows/commitlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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
# 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.
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
51 changes: 51 additions & 0 deletions .github/workflows/release-plz.yml
Original file line number Diff line number Diff line change
@@ -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 }}
61 changes: 61 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
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-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')
# 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:
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
46 changes: 38 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,44 @@ 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<VERSION> -m "Release v<VERSION>"`.
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 `<crate-name>-vX.Y.Z`. Pré-v0.4 usava workspace-wide unified versioning.

### Fluxo recomendado (release-plz, automatizado via CI)

[`release-plz`](https://release-plz.dev) é Rust-native, dispara automaticamente:

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 `<crate>-v<X.Y.Z>` + 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).

Trigger manual: Actions → release-plz → "Run workflow".

### 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 <version>`.
6. Rodar `scripts/benchmark_competitive.sh` (atualiza `release-competitive-log.md`).
7. Criar tag git assinada: `git tag -s <crate>-v<VERSION> -m "Release <crate> v<VERSION>"` (per-crate) ou `git tag -s v<VERSION>` (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).

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
57 changes: 57 additions & 0 deletions cliff.toml
Original file line number Diff line number Diff line change
@@ -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.version }}...HEAD
"""
Comment thread
JaimeJunr marked this conversation as resolved.

[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"
48 changes: 48 additions & 0 deletions cog.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# 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"

# ─── 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" }
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" }

# ─── Changelog (usado pelo `cog changelog`) ────────────────────────────────
[changelog]
authors = []
template = "remote"
remote = "github.com"
repository = "serverust"
owner = "JaimeJunr"
Loading