Skip to content
Merged
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
9 changes: 9 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
startup --host_jvm_args=-Xmx2g

common --enable_bzlmod
common --repo_env=AR
common --repo_env=CBINDGEN
common --repo_env=CC
common --repo_env=PATH
build --jobs=2
build --local_resources=memory=4096
test --test_output=errors
test --test_env=HOME
test --test_env=USER
build --action_env=AR
build --action_env=CC
build --action_env=PATH

Expand Down
6 changes: 6 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
bindings/ffi-c/include/stdbr.h linguist-generated=true
bindings/nodejs/index.js linguist-generated=true
bindings/nodejs/index.d.ts linguist-generated=true
bindings/python/python/stdbr/stdbr.pyi linguist-generated=true
core/src/municipio/generated.rs linguist-generated=true
tools/municipio_gen/ibge_municipios.json linguist-generated=true
210 changes: 203 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,219 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
CARGO_BUILD_JOBS: 2
CARGO_INCREMENTAL: 0

jobs:
flake:
name: Nix flake check
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2

- uses: cachix/cachix-action@ad2ddac53f961de1989924296a1f236fcfbaa4fc # v15
with:
name: nix-community
skipPush: true

- name: Check flake and static quality rules
run: nix flake check --no-update-lock-file --max-jobs 2 --cores 2

bazel:
name: Build & Test
name: Bazel test suite
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- uses: cachix/install-nix-action@v27
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
nix_path: nixpkgs=channel:nixos-unstable
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2

- uses: cachix/cachix-action@v15
- uses: cachix/cachix-action@ad2ddac53f961de1989924296a1f236fcfbaa4fc # v15
with:
name: nix-community
skipPush: true

- name: Build & Test
run: nix develop --command bazel test //...
- name: Run authoritative tests
run: nix develop --command bazel test //:all_tests

rust:
name: Cargo fmt, Clippy and rustdoc
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2
- name: Run Rust quality gates
run: nix develop --command tools/quality/quality.sh rust

node-generated:
name: Node.js generated files
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2
- name: Regenerate the NAPI-RS loader and declarations
working-directory: bindings/nodejs
run: nix develop ../.. --command npm ci
- name: Check generated files for drift
working-directory: bindings/nodejs
run: |
nix develop ../.. --command npm run build
git diff --exit-code -- index.js index.d.ts

coverage:
name: stdbr-core coverage
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2
- name: Enforce stdbr-core line coverage
run: nix develop --command tools/quality/quality.sh coverage

fuzz-build:
name: Compile fuzz targets
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2
- name: Compile fuzz targets with nightly Rust
run: nix develop --command tools/quality/quality.sh fuzz-build

compatibility:
name: MSRV 1.85 and no_std
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2
- name: Check minimum supported Rust version
run: nix develop --command tools/quality/quality.sh msrv
- name: Check no_std facade and core
run: nix develop --command tools/quality/quality.sh no-std

audit:
name: Dependency audit
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2
- name: Audit locked dependencies
run: nix develop --command tools/quality/quality.sh audit

semver:
name: Semver compatibility
if: github.event_name != 'push'
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: cachix/install-nix-action@ba0dd844c9180cbf77aa72a116d6fbc515d0e87b # v27
with:
extra_nix_config: |
experimental-features = nix-command flakes
max-jobs = 2
cores = 2
- name: Check published Rust API compatibility
run: nix develop --command tools/quality/quality.sh semver

required:
name: Build & Test
if: always()
needs:
- flake
- bazel
- rust
- node-generated
- coverage
- fuzz-build
- compatibility
- audit
- semver
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Require every quality gate
env:
EVENT_NAME: ${{ github.event_name }}
FLAKE_RESULT: ${{ needs.flake.result }}
BAZEL_RESULT: ${{ needs.bazel.result }}
RUST_RESULT: ${{ needs.rust.result }}
NODE_GENERATED_RESULT: ${{ needs['node-generated'].result }}
COVERAGE_RESULT: ${{ needs.coverage.result }}
FUZZ_RESULT: ${{ needs['fuzz-build'].result }}
COMPATIBILITY_RESULT: ${{ needs.compatibility.result }}
AUDIT_RESULT: ${{ needs.audit.result }}
SEMVER_RESULT: ${{ needs.semver.result }}
run: |
set -euo pipefail
for result in \
"$FLAKE_RESULT" \
"$BAZEL_RESULT" \
"$RUST_RESULT" \
"$NODE_GENERATED_RESULT" \
"$COVERAGE_RESULT" \
"$FUZZ_RESULT" \
"$COMPATIBILITY_RESULT" \
"$AUDIT_RESULT"; do
if [[ "$result" != success ]]; then
echo "required quality gate finished with: $result" >&2
exit 1
fi
done

if [[ "$SEMVER_RESULT" != success ]] && \
[[ ! ("$EVENT_NAME" == push && "$SEMVER_RESULT" == skipped) ]]; then
echo "semver gate finished with: $SEMVER_RESULT" >&2
exit 1
fi
75 changes: 59 additions & 16 deletions .github/workflows/ibge-sync.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: IBGE Sync Check
name: IBGE Municipality Sync

on:
schedule:
Expand All @@ -12,33 +12,76 @@ permissions:
jobs:
ibge-sync:
runs-on: ubuntu-latest
timeout-minutes: 20
concurrency:
group: ibge-municipality-sync
cancel-in-progress: false
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4

- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/nix-installer-action@b074b4ad5f255f9c8a6a2414a2f07e7f4f2925a3 # main

- uses: DeterminateSystems/magic-nix-cache-action@main
- uses: DeterminateSystems/magic-nix-cache-action@4119f6e7cfd06aaeee21273b2792c1fcb5d66ba1 # main

- name: IBGE sync test
id: sync_test
- name: Check generated data offline
run: nix develop --command bazel test //tools/municipio_gen:drift_test

- name: Fetch live IBGE municipalities
id: fetch
if: github.event_name == 'schedule'
continue-on-error: true
run: nix develop --command bazel test //tests/parity:parity_rust
env:
IBGE_URL: https://servicodados.ibge.gov.br/api/v1/localidades/municipios
run: |
curl --fail --silent --show-error --location \
--retry 3 --retry-all-errors --connect-timeout 15 --max-time 120 \
"$IBGE_URL" --output "$RUNNER_TEMP/ibge-municipios.json"

- name: Report IBGE network failure
if: always() && github.event_name == 'schedule' && steps.fetch.outcome == 'failure'
run: |
echo "::error title=IBGE network failure::The live API could not be downloaded; no files or PR were created."
exit 1

- name: Regenerate from live response
if: github.event_name == 'schedule' && steps.fetch.outcome == 'success'
run: |
nix develop --command bazel run //tools/municipio_gen -- \
generate --input "$RUNNER_TEMP/ibge-municipios.json" --update-source

- name: Validate regenerated data
if: github.event_name == 'schedule' && steps.fetch.outcome == 'success'
run: |
nix develop --command bazel test \
//tools/municipio_gen:drift_test //core:stdbr-core-test

- name: Regenerate municipality data
if: steps.sync_test.outcome == 'failure'
run: nix develop --command cargo run -p parity-gen > /tmp/municipio.rs
- name: Detect municipality drift
id: drift
if: github.event_name == 'schedule' && steps.fetch.outcome == 'success'
run: |
if git diff --quiet -- core/src/municipio/generated.rs tools/municipio_gen/ibge_municipios.json; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
status=$?
if [ "$status" -ne 1 ]; then
exit "$status"
fi
echo "changed=true" >> "$GITHUB_OUTPUT"
fi

- name: Create Pull Request if out of sync
if: steps.sync_test.outcome == 'failure'
uses: peter-evans/create-pull-request@v6
- name: Create pull request for municipality drift
if: steps.drift.outputs.changed == 'true'
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore(ibge): sync municipalities"
title: "chore(ibge): sync municipalities"
body: |
Automated IBGE sync detected differences between `core/src/municipio.rs` and the live IBGE API.
The scheduled sync detected municipality drift against the live IBGE API.

This PR regenerates the municipality data. Please review and merge to include it in the next release.
This PR updates the normalized source snapshot and `core/src/municipio/generated.rs`.
branch: chore/ibge-sync
labels: ibge-sync
add-paths: core/src/municipio.rs
add-paths: |
core/src/municipio/generated.rs
tools/municipio_gen/ibge_municipios.json
Loading
Loading