Skip to content

Latest commit

 

History

History
247 lines (198 loc) · 10.3 KB

File metadata and controls

247 lines (198 loc) · 10.3 KB

Development and verification

Prerequisites

  • Node.js 20.19.4 or newer (the repository uses Node 22 in CI).
  • Yarn 3.6.1 through the repository's checked-in Yarn release.
  • Android Studio/JDK 17 for Android work; the RN 0.73/0.74 compatibility fixture intentionally uses Gradle 8.3 (GRADLE_EXECUTABLE can select it locally).
  • Xcode and CocoaPods for iOS work.
  • Emscripten only when regenerating the checked-in WebAssembly bundle.

Install

yarn install --immutable

The root package is the library and example/ is the React Native consumer.

Core quality gates

yarn prepare
yarn typecheck
yarn lint
yarn test --runInBand
yarn test:native-operations

Web gates

yarn test:web
yarn test:web:browser
yarn test:web:metro
yarn test:package
yarn test:sdk
  • test:web checks the WebAssembly round trip and patch magic.
  • test:web:browser runs the public Worker API in Chrome.
  • test:web:metro proves Metro selects the .web entry rather than the native TurboModule facade.
  • test:package installs the real tarball into a clean consumer and verifies browser, ESM, CommonJS, TypeScript, and optional-peer behavior.
  • test:sdk installs the prepared RN tarball into an isolated Vite consumer and verifies /web and /toolkit, production resource loading, and real byte round trips.
  • test:web:package builds and checks the separate Web tarball, then verifies its root and /toolkit in a clean consumer without RN dependencies.
  • test:web:registry checks publication guards for missing versions, mismatched contents, network errors, signatures metadata, and provenance policy.

Native robustness and compatibility

FUZZ_RUNS=2000 yarn test:fuzz
scripts/test-rn-android-compatibility.sh 0.73.11 old
scripts/test-rn-android-compatibility.sh 0.73.11 new
scripts/test-rn-android-compatibility.sh 0.74.7 new
scripts/test-rn-android-compatibility.sh 0.86.0 new
scripts/test-rn-ios-compatibility.sh 0.73.11 old
scripts/test-rn-ios-compatibility.sh 0.73.11 new
scripts/test-rn-ios-compatibility.sh 0.74.7 new
scripts/test-rn-ios-compatibility.sh 0.86.0 new

The fuzz gate uses libFuzzer with AddressSanitizer and UndefinedBehaviorSanitizer when the local Clang runtime provides it, otherwise it runs a deterministic sanitizer corpus. The compatibility fixture compiles the actual Android module sources against the selected React Native artifact instead of relying on source-pattern assertions. test:native-operations deterministically covers job progress, cancellation, limits, malformed patches, atomic destination behavior, and temporary cleanup.

Run the repeatable Web and native performance baselines with:

yarn benchmark:web
BENCHMARK_OUTPUT=/tmp/web-wasm.json yarn benchmark:web
yarn benchmark:native
BENCHMARK_OUTPUT=/tmp/native-core.json yarn benchmark:native

Each input size runs in a fresh process. Both reports include peak resident memory; the Web report also records the resident, external, and ArrayBuffer memory still live after the round trip. Use the non-blocking large-file profile before changing buffer ownership or the patch format:

BENCHMARK_OUTPUT=/tmp/web-large.json yarn benchmark:large:web
BENCHMARK_OUTPUT=/tmp/native-large.json yarn benchmark:large:native

The large profile uses 16, 64, and 128 MiB fixtures and can consume several gigabytes of memory. It is intentionally not a pull-request gate. A manual Native Core Benchmark run accepts a comma-separated size list when a shared runner baseline is useful. Interpret the numbers with the scope and acceptance criteria in the large-file roadmap.

The published-package canaries install directly from npm and intentionally use current Vite and Expo toolchains. They are scheduled CI checks, not release gates. Run them on demand with yarn test:registry:vite and yarn test:registry:expo; set PACKAGE_SPEC to validate a tag or tarball.

Dependency security

The published package has no runtime npm dependencies; React and React Native are optional peers. Dependabot groups routine npm, Ruby, and Actions updates to keep review volume bounded. The lockfile also pins patched leaf versions where their APIs remain compatible.

yarn npm audit --all --recursive

The example and root toolchains track React Native 0.86, CLI 20.2, and release-it 20. The upgrades remove the vulnerable tmp and ip chains; the lockfile pins patched tar, fast-xml-parser, socks, and compatible leaf overrides reported by the audit. Recheck GitHub Dependabot alerts after dependency changes instead of assuming a lockfile override closes an advisory.

Site and documentation

yarn site:build
yarn site:test
yarn site:test:browser

The static output is written to site-dist/ and deployed by the GitHub Pages workflow. Markdown under docs/ is rendered into the site by the build script. English pages live directly under docs/; Chinese mirrors live under docs/zh-CN/. Keep both versions aligned when behavior or public API changes.

Rebuild WebAssembly

After changing files under cpp/, activate an Emscripten toolchain and run:

yarn build:web
yarn test:web
yarn test:web:browser

Commit both generated modules with the C source change. The Node-compatible web/bsdiffpatch.mjs includes NODEFS for /node and the CLI; the dedicated browser web/bsdiffpatch.browser.mjs excludes Node runtime branches for the /web Worker graph. Do not replace one with the other to hide a bundler warning.

Native verification

Android CI compiles the legacy boundary and New Architecture sources, then runs the public API through RN 0.86 New Architecture on API 24 and 31 for pull requests. iOS compiles the Pod compatibility fixtures and runs RN 0.86 New Architecture on Simulator; React Native 0.82 and newer no longer provide a legacy runtime. Device tests assert the active architecture, cross-platform golden patches, malformed-patch rejection, job progress, cancellation, limits, and output cleanup.

native-benchmark.yml is manual and scheduled infrastructure. It uploads Linux/macOS JSON baselines but is intentionally not a pull-request blocker because shared-runner performance is noisy.

For local example commands, see CONTRIBUTING.md.

Publishing checklist

  1. Run the core, Web, and site gates.
  2. Run yarn test:package, yarn test:sdk, and inspect npm pack --dry-run. The pack command runs the prepack contract check; use node scripts/check-package-contract.mjs for a direct check.
  3. Confirm public docs match the exported TypeScript declarations.
  4. Confirm English and Chinese public guides describe the same behavior.
  5. When the prepared package.json version is final, use yarn release --no-increment to create the release commit, tag, and GitHub Release. Run it only with explicit maintainer authorization.
  6. Publishing the GitHub Release starts npm-publish.yml. The workflow checks that the tag matches package.json, runs the release gates, publishes through npm Trusted Publishing, and verifies the provenance attestation.
  7. Verify the npm package and GitHub Release before announcing availability.

The npm package's Trusted Publisher is already configured with these values:

  • Provider: GitHub Actions.
  • Organization or user: JimmyDaddy.
  • Repository: react-native-bs-diff-patch.
  • Workflow filename: npm-publish.yml.
  • Environment: leave empty.

No npm-side change is required for a normal release, and the workflow does not use a long-lived npm token.

The checklist above is for the existing react-native-bs-diff-patch package. The standalone bs-diff-patch-web package is released independently under the web-v0.5.0 tag namespace and does not replace, deprecate, or republish the React Native package. Keep Node filesystem operations, the CLI, and their release tooling on react-native-bs-diff-patch. The standalone Web design documents the local first release, subsequent Trusted Publishing setup, web-npm-publish.yml, and byte-identical retry policy.

Recovering a failed npm publication

For an existing tag and published GitHub Release (the examples below use v0.5.0), recovery reuses that release. Check the registry before retrying a failed npm-publish.yml run:

npm view react-native-bs-diff-patch@0.5.0 version \
  dist.attestations.provenance.predicateType --registry=https://registry.npmjs.org/

If 0.5.0 is already published, do not publish it again. Finish only the provenance and registry smoke checks, such as PACKAGE_SPEC=react-native-bs-diff-patch@0.5.0 yarn test:sdk and the applicable yarn test:registry:vite or yarn test:registry:expo check. Proceed with a retry only when the official registry query confirms an explicit E404; network errors, 403 responses, timeouts, and any other ambiguous result must stop the recovery. After fixing the release tool or fixture, merge that fix into main and retry the existing GitHub Release from main:

gh workflow run npm-publish.yml --ref main -f release_tag=v0.5.0
gh run list --workflow npm-publish.yml --limit 5
gh run watch <run-id>

After the retry completes, inspect the run, provenance metadata, and registry smoke output before announcing availability.

The manual workflow accepts only an existing published GitHub Release. It checks out the exact refs/tags/<release_tag> commit and verifies that HEAD matches that tag, then checks the tag/package version, tag and workflow commit reachability from main, and that the npm version is not already present. It temporarily takes the test-sdk-consumers harness from the workflow commit for the quality gates, restores the tag script before packing, and asserts that the tracked tree is clean. The full quality gates, OIDC Trusted Publishing, provenance verification, and published-package smoke test remain enabled.

The npm 12 cross-version fixture resolves an exact package version through the official https://registry.npmjs.org/ registry and compares its expected SHA-512 SRI. Keep that exact-registry resolution; do not restore a download URL fixture or weaken its integrity assertion.

Do not move or delete the existing tag, run release-it again for the same version, or change the npm Trusted Publisher settings. A retry repairs the publication path for the existing release.