feat(ingest): single-transcript Claude hook fast-path + global --quiet #186
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: napi build | |
| # Build prebuilt napi-rs `.node` artifacts for every platform we publish to | |
| # npm under `@relayburn/sdk-*`. PRs validate the matrix; the cutover publish | |
| # workflow (`.github/workflows/publish.yml`) calls this workflow via | |
| # `workflow_call` to produce the `.node` files it then stages into | |
| # per-platform packages. | |
| # | |
| # Caches Cargo registry + git + target dir, plus pnpm store, so the matrix | |
| # stays fast on the hot path. | |
| on: | |
| pull_request: | |
| paths: | |
| - 'crates/relayburn-sdk/**' | |
| - 'crates/relayburn-sdk-node/**' | |
| - 'packages/sdk-node/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'rust-toolchain.toml' | |
| - '.github/workflows/napi-build.yml' | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'crates/relayburn-sdk/**' | |
| - 'crates/relayburn-sdk-node/**' | |
| - 'packages/sdk-node/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'rust-toolchain.toml' | |
| - '.github/workflows/napi-build.yml' | |
| workflow_dispatch: | |
| workflow_call: | |
| # Publish runs the same matrix this workflow exercises on PRs. The | |
| # caller downloads the uploaded `relayburn-sdk-<short>` artifacts and | |
| # stages them into `packages/sdk-node/npm/<short>/` before | |
| # `npm pack` + `npm publish`. | |
| inputs: | |
| release_version: | |
| description: >- | |
| Post-bump release version (e.g. "2.1.0") to bake into the | |
| napi-rs binding via CARGO_PKG_VERSION. Optional — when empty | |
| (PR/push runs) we skip the lockstep sed and build with the | |
| on-disk workspace version unchanged. | |
| required: false | |
| type: string | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: napi-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| name: build ${{ matrix.target }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - target: x86_64-apple-darwin | |
| os: macos-15-intel | |
| short: darwin-x64 | |
| - target: aarch64-apple-darwin | |
| os: macos-14 | |
| short: darwin-arm64 | |
| - target: x86_64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| short: linux-x64-gnu | |
| - target: aarch64-unknown-linux-gnu | |
| os: ubuntu-latest | |
| short: linux-arm64-gnu | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v5 | |
| - name: Setup Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '22.14.0' | |
| cache: 'pnpm' | |
| - name: Setup Rust toolchain | |
| # rust-toolchain.toml at the repo root pins channel + components. | |
| # `cross` handles the aarch64 linux target via container, so we | |
| # only register the host target by default and add the matrix | |
| # target explicitly when it's a supported native cross. | |
| run: | | |
| rustup toolchain install | |
| rustup target add ${{ matrix.target }} | |
| - name: Install aarch64-linux cross toolchain (linux-arm64 only) | |
| if: matrix.target == 'aarch64-unknown-linux-gnu' | |
| # `napi build` calls `cargo build --target aarch64-unknown-linux-gnu` | |
| # directly (it does not auto-route through `cross`), so we need a real | |
| # aarch64 cross-compiler available on the runner. `libsqlite3-sys` (a | |
| # transitive dep via `rusqlite`) compiles bundled SQLite C source via | |
| # `cc-rs`, which probes for `aarch64-linux-gnu-gcc`. | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-aarch64-linux-gnu | |
| - name: Cache cargo registry + target | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: cargo-${{ runner.os }}-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock', '**/Cargo.toml', 'rust-toolchain.toml') }} | |
| restore-keys: | | |
| cargo-${{ runner.os }}-${{ matrix.target }}- | |
| cargo-${{ runner.os }}- | |
| - name: Install workspace deps | |
| run: pnpm install --frozen-lockfile | |
| - name: Lockstep Cargo.toml to release version | |
| # When invoked via the publish workflow, sed the workspace | |
| # `[workspace.package].version` (and the path-dep `version = "X.Y"` | |
| # pin in `crates/relayburn-sdk-node/Cargo.toml`) so the napi-rs | |
| # binding built below carries the post-bump `CARGO_PKG_VERSION`. | |
| # Mirrors the lockstep regex in publish.yml and cli-build.yml. | |
| # | |
| # Skipped when `release_version` is empty (PR/push runs). | |
| if: inputs.release_version != '' | |
| run: | | |
| set -euo pipefail | |
| RUST_VER="${{ inputs.release_version }}" | |
| RUST_MINOR=$(echo "$RUST_VER" | awk -F. '{print $1"."$2}') | |
| echo "Rust workspace lockstep: $RUST_VER (minor pin: $RUST_MINOR)" | |
| sed -i.bak -E "s/^version = \"[^\"]+\"$/version = \"$RUST_VER\"/" Cargo.toml | |
| sed -i.bak -E "s|(relayburn-sdk = \\{ path = \"\\.\\./relayburn-sdk\", version = \")[^\"]+(\" \\})|\\1$RUST_MINOR\\2|" crates/relayburn-sdk-node/Cargo.toml | |
| rm -f Cargo.toml.bak crates/relayburn-sdk-node/Cargo.toml.bak | |
| - name: Build napi binding for ${{ matrix.target }} | |
| # `napi build` reads `packages/sdk-node/package.json`'s `napi` | |
| # block to learn the binary name, then dispatches to `cargo build` | |
| # under the hood. The output is a per-target `.node` file plus a | |
| # generated `binding.cjs` / `binding.d.ts`. | |
| # | |
| # We pass `src` as the positional `[destDir]` so all three outputs | |
| # (`.node`, `binding.cjs`, `binding.d.ts`) land in `src/` next to | |
| # `index.js`. The generated `binding.cjs` resolves the local `.node` | |
| # via `existsSync(join(__dirname, 'index.<target>.node'))`, and | |
| # `__dirname` is `packages/sdk-node/src/`, so co-locating the | |
| # artifacts is the simplest way to make the local-binding branch | |
| # actually fire (without it, the loader silently falls through to | |
| # `require('@relayburn/sdk-<target>')`, which isn't installed in | |
| # dev). The `--js` / `--dts` paths are relative to the destDir so | |
| # `pnpm exec napi build … --js binding.cjs --dts binding.d.ts src` | |
| # writes to `src/binding.{cjs,d.ts}` (passing `src/binding.cjs` plus | |
| # `src` would double-prefix to `src/src/binding.cjs`). | |
| # | |
| # `--cargo-cwd` points at the binding crate (which lives under | |
| # `crates/relayburn-sdk-node/`, not co-located with the npm package) | |
| # so the `cargo metadata` step that resolves the cdylib succeeds. | |
| # The CC_/linker env vars only take effect for the aarch64-linux leg | |
| # (cargo ignores per-target vars when the host matches the target); | |
| # native legs are unaffected. | |
| working-directory: packages/sdk-node | |
| env: | |
| CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc | |
| CXX_aarch64_unknown_linux_gnu: aarch64-linux-gnu-g++ | |
| CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc | |
| run: | | |
| pnpm exec napi build \ | |
| --platform \ | |
| --release \ | |
| --target ${{ matrix.target }} \ | |
| --cargo-cwd ../../crates/relayburn-sdk-node \ | |
| --js binding.cjs \ | |
| --dts binding.d.ts \ | |
| src | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: relayburn-sdk-${{ matrix.short }} | |
| path: packages/sdk-node/src/*.node | |
| if-no-files-found: warn | |
| retention-days: 7 | |
| - name: Bundle smoke test (esbuild) | |
| # Confirms the umbrella facade resolves + bundles cleanly. Runs on | |
| # every matrix leg so we catch platform-specific resolution issues | |
| # (path casing, native-binding aliases) close to where they'd | |
| # surface for an embedder. | |
| working-directory: packages/sdk-node | |
| run: node --test 'test/esbuild-smoke.test.js' | |
| - name: Native SDK smoke test | |
| # The suite runs the Node facade against the committed cli-golden | |
| # ledger and checks stable result shapes for the exported verbs. | |
| # | |
| # Skipped on the aarch64-linux leg: that leg is a CROSS-COMPILE | |
| # (host=ubuntu-latest x64, target=aarch64-unknown-linux-gnu), so | |
| # the only `.node` artifact present is the arm64 binary. The | |
| # x64 `node` interpreter on the runner cannot load it — and | |
| # `binding.cjs` resolves the binding by `process.arch`, so it | |
| # tries to load `index.linux-x64-gnu.node` (or the matching | |
| # optionalDependency, which isn't installed in dev) and crashes | |
| # the import before the test body's `t.skip` can fire. The other | |
| # three legs (x64-darwin, arm64-darwin, x64-linux) are all native | |
| # and exercise the same conformance contract; this leg's job is | |
| # purely to validate the cross-compile build + artifact upload. | |
| # | |
| if: matrix.target != 'aarch64-unknown-linux-gnu' | |
| working-directory: packages/sdk-node | |
| env: | |
| RELAYBURN_SDK_NAPI_BUILT: '1' | |
| run: node --test 'test/conformance.test.js' |