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
7 changes: 7 additions & 0 deletions .changeset/native-debug-builds-outside-release.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@prosopo/native-ja4": patch
"@prosopo/native-merkle": patch
"@prosopo/native-puzzle": patch
---

The Rust addons now build in debug mode unless `NODE_ENV=production`, so local builds and CI tests stop paying for full link-time optimisation. Production builds (npm publish, the provider image) still run `build:release` with full LTO. Dependencies are optimised even in debug so tests stay fast, and the CI `cargo test` job now runs in debug with a cargo cache instead of a cold release build.
82 changes: 82 additions & 0 deletions .github/workflows/cargo-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# The napi crates carry Rust unit tests that `pnpm run test:all` never runs:
# turbo only drives the JS suites. Its own workflow, not a tests.yml job, so a
# Rust failure is reported on its own and does not wait for the full JS build,
# and so it runs only when a crate can have changed.

name: cargo-test

on:
pull_request:
branches: [main, dev, staging, release/*]
# Safe against the "required check never reports" trap: required-check.yml
# publishes `check` with no path filter and waits on every check run, so a
# PR touching neither path still gets a `check`.
paths:
- 'packages/native-*/**'
- '.github/workflows/cargo-test.yml'
types:
- opened
- synchronize
- reopened
- ready_for_review
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: "0"
CARGO_PROFILE_DEV_DEBUG: line-tables-only

defaults:
run:
shell: bash

jobs:
cargo-test:
name: cargo test (${{ matrix.crate }})
# Hosted for the same reason as tests.yml: this repository is public.
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false
strategy:
fail-fast: false
matrix:
# Independent crates, each with its own lockfile. A new
# packages/native-* crate is not tested until it is listed here.
crate:
[packages/native-ja4, packages/native-merkle, packages/native-puzzle]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: false

- name: Record the rustc version for the cache key
id: rustc-version
run: |
release=$(rustc -vV | sed -n 's/^release: //p')
commit=$(rustc -vV | sed -n 's/^commit-hash: //p')
if [ -z "$release" ]; then
echo "::error::could not read release from rustc -vV"; exit 1
fi
echo "version=${release}${commit:+-${commit:0:9}}" >> "$GITHUB_OUTPUT"

# The compiler goes in prefix-key, not just key: rust-cache derives its
# restore-keys from the prefix, so a version left outside it can restore a
# target/ built by another rustc, which cargo rejects with E0514.
- name: Cache cargo
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
workspaces: ${{ matrix.crate }}
prefix-key: v0-rust-${{ steps.rustc-version.outputs.version }}

# Debug, not --release: the release profile's fat LTO and single codegen
# unit are for the shipped addon, and only slow a test build down. The
# dependencies are still optimised via profile.dev.package."*".
- name: cargo test
working-directory: ${{ matrix.crate }}
run: cargo test --locked
27 changes: 2 additions & 25 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ jobs:
# way CSS allows, and the ones that size it by *measuring* it have broken
# repeatedly and silently: the widget renders, just at its minimum width.
#
# Kept out of `check` for the same reason as cargo-test, and because it needs
# none of what that job builds -- no docker, no provider, no workspace build,
# Kept out of `check` so its failure is reported on its own, and because it
# needs none of what that job builds -- no docker, no provider, no workspace build,
# since the package imports nothing from the workspace at runtime. It still
# gates the merge: required-check.yml waits on every check run on the commit,
# so there is no list to add this to.
Expand All @@ -189,26 +189,3 @@ jobs:
run: pnpm --filter @prosopo/widget-skeleton exec playwright install --with-deps chromium

- run: pnpm --filter @prosopo/widget-skeleton run test:browser

# The napi crates carry Rust unit tests that `pnpm run test:all` never runs:
# turbo only drives the JS suites. Kept out of `check` so a Rust failure is
# reported on its own and does not wait for the full JS build.
cargo-test:
name: cargo test (${{ matrix.crate }})
runs-on: ubuntu-latest
if: github.event.pull_request.draft == false
strategy:
fail-fast: false
matrix:
# Independent crates, each with its own lockfile. A new
# packages/native-* crate is not tested until it is listed here.
crate:
[packages/native-ja4, packages/native-merkle, packages/native-puzzle]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
submodules: false

- name: cargo test
working-directory: ${{ matrix.crate }}
run: cargo test --release --locked
5 changes: 5 additions & 0 deletions packages/native-ja4/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,10 @@ strip = "symbols"
# Debug symbols for our own crate only. Dependency debuginfo is the bulk of a
# dev build and nobody steps through third-party code here; CI narrows our own
# to line tables via CARGO_PROFILE_DEV_DEBUG.
#
# Dependencies optimised even in debug: they compile once and are cached, so
# tests run near release speed while our own crate still rebuilds quickly.
# Releases keep full LTO via `build:release` (`NODE_ENV=production pnpm build`).
[profile.dev.package."*"]
debug = false
opt-level = 2
5 changes: 3 additions & 2 deletions packages/native-ja4/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
"targets": ["x86_64-unknown-linux-gnu"]
},
"scripts": {
"build": "napi build --platform --release",
"build": "if [ \"$NODE_ENV\" = production ]; then pnpm run build:release; else pnpm run build:debug; fi",
"build:debug": "napi build --platform",
"build:release": "napi build --platform --release",
"test": "node --test \"tests/**/*.test.ts\"",
"test:cargo": "cargo test --release",
"test:cargo": "cargo test",
"clean": "cargo clean && rm -f *.node index.js index.d.ts"
},
"devDependencies": {
Expand Down
5 changes: 5 additions & 0 deletions packages/native-merkle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,10 @@ strip = "symbols"
# Debug symbols for our own crate only. Dependency debuginfo is the bulk of a
# dev build and nobody steps through third-party code here; CI narrows our own
# to line tables via CARGO_PROFILE_DEV_DEBUG.
#
# Dependencies optimised even in debug: they compile once and are cached, so
# tests run near release speed while our own crate still rebuilds quickly.
# Releases keep full LTO via `build:release` (`NODE_ENV=production pnpm build`).
[profile.dev.package."*"]
debug = false
opt-level = 2
5 changes: 3 additions & 2 deletions packages/native-merkle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
"targets": ["x86_64-unknown-linux-gnu"]
},
"scripts": {
"build": "napi build --platform --release",
"build": "if [ \"$NODE_ENV\" = production ]; then pnpm run build:release; else pnpm run build:debug; fi",
"build:debug": "napi build --platform",
"test:cargo": "cargo test --release",
"build:release": "napi build --platform --release",
"test:cargo": "cargo test",
"clean": "cargo clean && rm -f *.node index.js index.d.ts"
},
"devDependencies": {
Expand Down
4 changes: 4 additions & 0 deletions packages/native-puzzle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@ lto = true
codegen-units = 1
strip = "symbols"

# Dependencies optimised even in debug: they compile once and are cached, so
# tests run near release speed while our own crate still rebuilds quickly.
# Releases keep full LTO via `build:release` (`NODE_ENV=production pnpm build`).
[profile.dev.package."*"]
debug = false
opt-level = 2
7 changes: 4 additions & 3 deletions packages/native-puzzle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
"targets": ["x86_64-unknown-linux-gnu"]
},
"scripts": {
"build": "napi build --platform --release",
"build": "if [ \"$NODE_ENV\" = production ]; then pnpm run build:release; else pnpm run build:debug; fi",
"build:debug": "napi build --platform",
"bench": "node bench.mjs",
"test:cargo": "cargo test --release",
"build:release": "napi build --platform --release",
"bench": "pnpm run build:release && node bench.mjs",
"test:cargo": "cargo test",
"test": "node --test tests/dimensions.test.ts",
"clean": "cargo clean && rm -f *.node"
},
Expand Down
Loading