ci: run linting without building native code - #435
Conversation
The lint job set up a full native toolchain (JDK 17, Android SDK + NDK, x86_64-linux-android Rust target) and ran two native bootstraps purely to get generated TypeScript types for type-checking. Resolve both TODOs: - Add `ferric build --dts-only`, which generates a crate's `.d.ts` and JS entrypoint via a plain host `cargo build` (napi-rs typedef codegen), without cross-compiling any Android/Apple binaries. The library basename is derived from `cargo metadata`'s cdylib target instead of from built artifact paths, so no platform build is needed to compute it. Wire this up as `ferric-example`'s new `build:types` script. - Use `weak-node-api`'s existing `prebuild:prepare` script (header copy + C++/TS declaration codegen) instead of `bootstrap` (which also runs the native CMake build). It already required nothing beyond clang-format. With both native builds no longer needed for typing, the lint job drops the JDK 17, Android SDK, and `rustup target add` steps entirely. Verified locally (Node 24, cargo present, no Android/Apple SDK): fresh `pnpm install && pnpm run build`, then `pnpm --filter weak-node-api run prebuild:prepare`, `pnpm --filter @react-native-node-api/ferric-example run build:types`, `pnpm run lint`, `pnpm run prettier:check`, `pnpm run depcheck` and `pnpm run publint` all pass end-to-end with no native toolchain present, reproducing the new lint job's steps. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm
|
I suspect we cannot trust that |
…ding them kraenhansen suspected generateTypeScriptDeclarations doesn't actually skip a native build. Confirmed: napi-rs's `napi build` has no typegen-only mode — it always runs a real `cargo build`, and --dts-only leaves a fully populated ~123MB target/ directory (including a compiled libferric_example.so) behind. "Skipping the native build entirely" was wrong; only Android/Apple cross-compilation was actually skipped, and the lint job stayed coupled to the host Rust toolchain's health exactly as #414 wanted to avoid. Switch to the issue's other suggested option: commit ferric_example.d.ts and ferric_example.js as a checked-in fixture (no longer gitignored), and drop the ferric-example build:types step from the lint job entirely — it no longer needs to regenerate anything. --dts-only stays, now documented accurately, as the way to regenerate the fixture by hand after changing packages/ferric-example/src/lib.rs. To catch drift, the two CI jobs that already do a real `ferric build` (Android and Apple triplets) now `git diff --exit-code` the two committed files right after building. Both are label-gated rather than running on every PR, so this doesn't fully close the gap — flagged in the PR thread. Also excludes the two fixture files from Prettier: they're left in napi-rs's own output formatting so regenerating them reproduces the committed bytes exactly, and the new drift check doesn't false-positive on formatting alone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm
|
Confirmed the suspicion — Pushed a fix (63f12e8) that switches to the issue's other suggested option: To guard against the fixture drifting from the Rust source, the two CI jobs that already do a real 🤖 Generated with Claude Code https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm Generated by Claude Code |
Per review feedback on #435. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm
* ci: run linting without building native code (#414) The lint job set up a full native toolchain (JDK 17, Android SDK + NDK, x86_64-linux-android Rust target) and ran two native bootstraps purely to get generated TypeScript types for type-checking. Resolve both TODOs: - Add `ferric build --dts-only`, which generates a crate's `.d.ts` and JS entrypoint via a plain host `cargo build` (napi-rs typedef codegen), without cross-compiling any Android/Apple binaries. The library basename is derived from `cargo metadata`'s cdylib target instead of from built artifact paths, so no platform build is needed to compute it. Wire this up as `ferric-example`'s new `build:types` script. - Use `weak-node-api`'s existing `prebuild:prepare` script (header copy + C++/TS declaration codegen) instead of `bootstrap` (which also runs the native CMake build). It already required nothing beyond clang-format. With both native builds no longer needed for typing, the lint job drops the JDK 17, Android SDK, and `rustup target add` steps entirely. Verified locally (Node 24, cargo present, no Android/Apple SDK): fresh `pnpm install && pnpm run build`, then `pnpm --filter weak-node-api run prebuild:prepare`, `pnpm --filter @react-native-node-api/ferric-example run build:types`, `pnpm run lint`, `pnpm run prettier:check`, `pnpm run depcheck` and `pnpm run publint` all pass end-to-end with no native toolchain present, reproducing the new lint job's steps. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm * ci: commit ferric-example's declarations as a fixture instead of building them kraenhansen suspected generateTypeScriptDeclarations doesn't actually skip a native build. Confirmed: napi-rs's `napi build` has no typegen-only mode — it always runs a real `cargo build`, and --dts-only leaves a fully populated ~123MB target/ directory (including a compiled libferric_example.so) behind. "Skipping the native build entirely" was wrong; only Android/Apple cross-compilation was actually skipped, and the lint job stayed coupled to the host Rust toolchain's health exactly as #414 wanted to avoid. Switch to the issue's other suggested option: commit ferric_example.d.ts and ferric_example.js as a checked-in fixture (no longer gitignored), and drop the ferric-example build:types step from the lint job entirely — it no longer needs to regenerate anything. --dts-only stays, now documented accurately, as the way to regenerate the fixture by hand after changing packages/ferric-example/src/lib.rs. To catch drift, the two CI jobs that already do a real `ferric build` (Android and Apple triplets) now `git diff --exit-code` the two committed files right after building. Both are label-gated rather than running on every PR, so this doesn't fully close the gap — flagged in the PR thread. Also excludes the two fixture files from Prettier: they're left in napi-rs's own output formatting so regenerating them reproduces the committed bytes exactly, and the new drift check doesn't false-positive on formatting alone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm * ci: drop the explanatory comment from ferric-example/.gitignore Per review feedback on #435. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm --------- Co-authored-by: Claude <noreply@anthropic.com>
What
Resolves both
TODOs in thelintjob of.github/workflows/check.yml, so the job no longer needs a native (JDK/Android SDK/NDK/Rust-Android) toolchain just to type-check TypeScript.weak-node-api— the lint job now runs the existingpnpm --filter weak-node-api run prebuild:preparescript instead ofbootstrap.prebuild:prepare(header copy + C++/TS declaration codegen) already didn't touch anything native — it only needsclang-format, which the job already installs viaaminya/setup-cpp.bootstrapadditionally ranprebuild:build(the actual CMake/NDK/Xcode native compile), which was never needed for typing.ferric-example— added a newferric build --dts-onlyflag. It runs a plain hostcargo build(napi-rs's typedef codegen) to emit the crate's.d.tsand JS entrypoint, without cross-compiling any Android/Apple binaries. The output library basename is now derived fromcargo metadata's cdylib target name instead of from the paths of already-built platform artifacts (previouslydetermineLibraryBasenamewouldassert()-fail on an empty array wheneverANDROID_HOME/darwin weren't present, sinceferric build's target auto-detection produced zero targets). Wired up asferric-example's newbuild:typesscript.With both native builds no longer needed, the JDK 17, Android SDK, and
rustup target add x86_64-linux-androidsteps are removed from thelintjob entirely.What CI will actually verify
This is a CI-infrastructure change — the important verification (that the new lint job steps work correctly on GitHub's runners without the JDK/Android SDK/NDK installed) can only be confirmed by this PR's own
lintjob run, not by me locally. What I did verify locally on a Linux worker with Node 24 andcargopresent, but no Android SDK, NDK, or JDK, reproducing the new job's steps end-to-end:All of these passed, and the generated
ferric_example.d.ts/.jsmatched what a fullferric buildwould produce (export declare function sum(a: number, b: number): number). I also confirmed the previous behavior actually failed the way I expected:ferric buildwith no explicit targets on this same toolchain-less box throwsAssertionError: Expected at least one library path to determine its basename(fromdetermineLibraryBasename), which is exactly the bug the JDK/Android SDK setup was masking by makingANDROID_HOMEavailable.I could not exercise the actual GitHub Actions runner environment, self-hosted caching, or the interaction with
ccache/aminya/setup-cppin situ — that's what this PR's CI run itself needs to confirm.Addresses #414. Confident enough in both halves that this should let the whole issue close once CI is green — flagging as "addresses" rather than "closes" until the actual CI run confirms it holds up on GitHub's infrastructure.
🤖 Generated with Claude Code
https://claude.ai/code/session_01DaK9eAAF5G8wj6UT8VekAm
Generated by Claude Code