Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ jobs:
- name: Build the wasm package
run: bun run build

# `bun run build` regenerates the type file. If what it produced differs
# from what is committed, the tarball's .d.ts would not be the reviewed
# one — which is how a build with missing sources shipped a .d.ts
# referencing types it no longer declared.
- name: Fail if the generated types drifted
run: git diff --exit-code -- src/generated_types.rs

- name: Run Tests with Bun
run: bun test
env:
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,13 @@ jobs:
- name: Build the wasm package
run: bun run build

# `bun run build` regenerates the type file. If what it produced differs
# from what is committed, the tarball's .d.ts would not be the reviewed
# one — which is how a build with missing sources shipped a .d.ts
# referencing types it no longer declared.
- name: Fail if the generated types drifted
run: git diff --exit-code -- src/generated_types.rs

- run: bun test

- name: Rust unit tests (wasm32 in Node)
Expand Down Expand Up @@ -322,6 +329,12 @@ jobs:
- name: Build the wasm package
run: bun run build

# The tarball is built from this step's output, so the same drift
# check applies here: publish what was reviewed, not what a runner
# happened to regenerate.
- name: Fail if the generated types drifted
run: git diff --exit-code -- src/generated_types.rs

# `--ignore-scripts` below suppresses the prepack hook, and prepack is
# where the tarball guard lives — run it directly so a build that leaks
# pkg/ or duplicate files still fails before publishing.
Expand Down
37 changes: 37 additions & 0 deletions codegen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ use walkdir::WalkDir;

/// Find whatsapp-rust source dir from Cargo's git cache by parsing Cargo.lock.
/// Falls back to `../../whatsapp-rust/` for local development.
///
/// This crate does not depend on whatsapp-rust, so `cargo run` never fetches
/// it: the sources have to already be on disk. On a machine where they are not
/// — a CI runner with a cold cache, where `gen` runs before anything downloads
/// the core — every lookup below misses, and `WalkDir` over a missing directory
/// yields nothing rather than erroring. That silently produced a type file with
/// almost everything missing, which still compiled and shipped a `.d.ts`
/// referencing types it no longer declared. Hence `require_sources`.
fn find_whatsapp_rust_root() -> PathBuf {
// Try to find it in Cargo's git checkout cache
let lock_path = Path::new("../Cargo.lock");
Expand Down Expand Up @@ -55,8 +63,25 @@ fn find_whatsapp_rust_root() -> PathBuf {
fallback
}

/// Refuse to generate from sources that are not there. Parsing nothing is not
/// an empty result, it is a broken one.
fn require_sources(root: &Path) {
let wacore = root.join("wacore/src");
Comment thread
jlucaso1 marked this conversation as resolved.
Outdated
if !wacore.is_dir() {
Comment thread
jlucaso1 marked this conversation as resolved.
Outdated
panic!(
"whatsapp-rust sources not found at {}\n\
Expected {} to exist. This generator reads the core's sources off disk and \n\
does not fetch them: run a cargo build first so the git checkout is populated, \n\
or clone whatsapp-rust next to this repository.",
root.display(),
wacore.display()
);
}
}

fn main() {
let root = find_whatsapp_rust_root();
require_sources(&root);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fetch the core before requiring its checkout

On a fresh clone or GitHub-hosted runner, bun run build invokes gen:bridge-types before any root-crate Cargo command can materialize the whatsapp-rust checkout, so this call panics when no sibling clone exists. In particular, the build-and-test job and the separate publish job go from bun install directly to this build; Swatinem/rust-cache caches Cargo's git database/build outputs rather than guaranteeing the working checkout expected here. Add an explicit cargo fetch/cargo metadata step before these builds, or make the generator populate the checkout itself, so the documented full-build command and release publish work on clean machines.

AGENTS.md reference: AGENTS.md:L97-L103

Useful? React with 👍 / 👎.

let wacore_dir = root.join("wacore/src");
let src_dir = root.join("src");

Expand Down Expand Up @@ -89,6 +114,18 @@ fn main() {
// Also parse send.rs for SendOptions/RevokeType
parse_file(&src_dir.join("send.rs"), &mut all_types);

// Reported so a collapse is visible in the build log. Deliberately not
// asserted against a floor: the real count is what it is, and a threshold
// close to it breaks every legitimate change to the core. What guards the
// output is `require_sources` above and the drift check in CI, which
// compares against the committed file instead of guessing a number.
eprintln!("parsed {} types from {}", all_types.len(), root.display());
assert!(
!all_types.is_empty(),
"no types parsed from {}: refusing to generate an empty type file",
root.display()
);

// Build TypeScript content
let mut ts = String::new();

Expand Down