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
50 changes: 49 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ jobs:
strategy:
fail-fast: false
matrix:
react-native: ['0.81', '0.83', '0.86', '0.87']
react-native: ['0.81', '0.82', '0.83', '0.84', '0.85', '0.86', '0.87']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
Expand All @@ -196,6 +196,54 @@ jobs:
# and swapping the npm dependency does not swap the project.
- run: ./scripts/check-rn-compat.sh ${{ matrix.react-native }}

# The packed tarballs installed into a fresh `react-native init` app, as a
# customer gets them from npm (scripts/check-pack-install.sh). Inside the
# workspace every lookup finds the repo root and the repo's own tsconfig,
# so none of the jobs above can see what this does: native-versions.json
# missing from the tarball broke Gradle and pod install for every npm
# install (BLK-17), and the app's own `tsc` failed on 0.87 (API-49).
# Typecheck on every supported minor; Gradle configuration on the floor
# and the latest.
pack-install:
name: pack install (${{ matrix.react-native }}${{ matrix.android && ', android' || '' }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
react-native: ['0.81', '0.82', '0.83', '0.84', '0.85', '0.86', '0.87']
include:
- react-native: '0.81'
android: true
- react-native: '0.87'
android: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22.18'
- uses: actions/setup-java@v4
if: matrix.android
with:
distribution: temurin
java-version: 17
- run: ./scripts/check-pack-install.sh ${{ matrix.react-native }} --typecheck ${{ matrix.android && '--android' || '' }}

# The iOS half: `pod install` evaluates both podspecs from the tarballs and
# vendors the SDK (BLK-17).
pack-install-ios:
name: pack install (${{ matrix.react-native }}, ios)
runs-on: macos-15
strategy:
fail-fast: false
matrix:
react-native: ['0.81', '0.87']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22.18'
- run: ./scripts/check-pack-install.sh ${{ matrix.react-native }} --ios

android:
name: android
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ packages/react-native-feedback/BugseeFeedbackSources/
reports/
packages/react-native/.bugsee-xcframework-version
packages/react-native-feedback/.bugsee-feedback-sources-version

# Staged into each package by prepack (scripts/pack-native-versions.ts) and
# removed by postpack; the repo-root file is the only source.
packages/*/native-versions.json
4 changes: 3 additions & 1 deletion docs/design/2026-09-15-sdk-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ The floor is a reach decision, and reach is not linear in the version number. A

0.81 still permits opting out of the New Architecture, so support there is **conditional on it being enabled** — the default since 0.76. That is a documented requirement, not a legacy fallback: still one native source set per platform, a TurboModule spec with no legacy path, and no interop shims.

**Hermes is required; JavaScriptCore (Hermes off) is not supported** (decided 2026-10-07 for the first beta). React Native removed JSC from core in 0.81; the replacement, `@react-native-community/javascriptcore` (0.2.0, March 2025), does not work with current React Native: on Android its 2019 JSC cannot parse React Native's own bundle (`??`/`?.`), and on iOS it fails to link on 0.87 and to `pod install` on 0.86 (campaign build lane, MX-HERMES-OFF). The wrapper still reports `js-engine: jsc` and the source-map hook still handles a plain bundle when Hermes is off; neither is a supported configuration.

0.80 is the hard technical floor. `codegenConfig.ios.modulesProvider`, which is how the TurboModule avoids colliding with the SDK's own `Bugsee` class (§6.4), does not exist before 0.80. 0.81 clears it with a version to spare.

---
Expand Down Expand Up @@ -113,7 +115,7 @@ It is not merely an identity struct. It extends `ReportHandler` *and* `DataReque
|---|---|
| `getWrapperType()` / `wrapperType` | `"react_native"` |
| `getWrapperVersion()` / `getWrapperBuild()` | package version and build |
| `getContext()` / `context` | RN version, JS engine (Hermes/JSC), build configuration |
| `getContext()` / `context` | RN version, JS engine (`hermes`; `jsc` is still reported if Hermes is off, though that is unsupported, §4.5), build configuration |
| `onLifecycleEvent(name, data)` | lifecycle delivery; fires **before** the app's own listener |
| `getSecureRectangles(display)` / `secureRectsForDisplay:` | pull-based secure rectangles |
| `ReportHandler` callbacks | attachments and report mutation; fire **before** the app's `setReportHandler` |
Expand Down
33 changes: 23 additions & 10 deletions packages/react-native-feedback/BugseeReactNativeFeedback.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
require 'json'

package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
native = JSON.parse(File.read(File.join(__dir__, '..', '..', 'native-versions.json')))
# The one source of every native pin. In this repo it is the root file. In an
# app the package sits in node_modules, where the root file is not above it, so
# prepack ships a copy at the package root (scripts/pack-native-versions.ts);
# that copy is read first.
native_versions_file = [
File.join(__dir__, 'native-versions.json'),
File.join(__dir__, '..', '..', 'native-versions.json'),
].find { |path| File.file?(path) }
raise "native-versions.json not found in #{__dir__} or the repo root above it" unless native_versions_file
native = JSON.parse(File.read(native_versions_file))

Pod::Spec.new do |s|
s.name = 'BugseeReactNativeFeedback'
Expand Down Expand Up @@ -49,16 +58,20 @@ Pod::Spec.new do |s|
VERSION="#{native['ios']['sdk']}"
STAMP=".bugsee-feedback-sources-version"
if [ ! -d "BugseeFeedbackSources" ] || [ "$(cat "${STAMP}" 2>/dev/null)" != "${VERSION}" ]; then
rm -rf "BugseeFeedbackSources"
ARCHIVE="/tmp/feedback-spm-${VERSION}.tar.gz"
curl -sSfL -o "${ARCHIVE}" \
# A download directory of this run's own, not a fixed /tmp path that
# concurrent pod installs share; the sources are staged beside their
# destination and renamed into place, so a failure leaves nothing.
WORK="$(mktemp -d "${TMPDIR:-/tmp}/bugsee-feedback.XXXXXX")"
STAGE="$(mktemp -d "./.bugsee-feedback.XXXXXX")"
trap 'rm -rf "${WORK}" "${STAGE}"' EXIT
curl -sSfL -o "${WORK}/feedback-spm.tar.gz" \
"https://codeload.github.com/bugsee/feedback-spm/tar.gz/refs/tags/${VERSION}"
STAGE="$(mktemp -d)"
tar -xzf "${ARCHIVE}" -C "${STAGE}"
SRC="$(echo "${STAGE}"/feedback-spm-*/Sources/BugseeFeedback)"
mkdir -p "BugseeFeedbackSources"
cp -R "${SRC}/." "BugseeFeedbackSources/"
rm -rf "${STAGE}" "${ARCHIVE}"
tar -xzf "${WORK}/feedback-spm.tar.gz" -C "${WORK}"
SRC="$(echo "${WORK}"/feedback-spm-*/Sources/BugseeFeedback)"
mkdir "${STAGE}/BugseeFeedbackSources"
cp -R "${SRC}/." "${STAGE}/BugseeFeedbackSources/"
rm -rf "BugseeFeedbackSources"
mv "${STAGE}/BugseeFeedbackSources" "BugseeFeedbackSources"
printf '%s' "${VERSION}" > "${STAMP}"
fi
CMD
Expand Down
5 changes: 4 additions & 1 deletion packages/react-native-feedback/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ do not have to depend on this package.
## Requirements

The same as `@bugsee/react-native`: React Native 0.81 or later with the New
Architecture, iOS 15.0 or later, Android API 21 or later.
Architecture, Hermes, iOS 15.0 or later, Android API 21 or later. Hermes is
required; JavaScriptCore (Hermes off) is not supported: React Native removed
JSC from core in 0.81, and the community package does not work with current
React Native.

## Install

Expand Down
7 changes: 6 additions & 1 deletion packages/react-native-feedback/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
"main": "src/index.ts",
"files": [
"src",
"!src/**/__tests__",
"!src/testSupport",
"android",
"!android/src/test",
"ios",
"react-native.config.js",
"*.podspec",
"native-versions.json",
"LICENSE",
"README.md"
],
Expand All @@ -23,7 +27,8 @@
"react-native": "0.87.1"
},
"scripts": {
"prepack": "node ../../scripts/cli-check-releasable-pins.ts"
"prepack": "node ../../scripts/cli-check-releasable-pins.ts && node ../../scripts/cli-pack-native-versions.ts stage",
"postpack": "node ../../scripts/cli-pack-native-versions.ts unstage"
},
"codegenConfig": {
"name": "RNBugseeFeedbackSpec",
Expand Down
10 changes: 6 additions & 4 deletions packages/react-native-feedback/src/NativeBugseeFeedback.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { TurboModule } from 'react-native';
// CodegenTypes from the package root: 0.87 declares no types for the deep
// `react-native/Libraries/Types/CodegenTypes` path unless the consumer opts in,
// and this file is compiled by the consumer's tsc (API-49).
import type { CodegenTypes, TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
import type { EventEmitter } from 'react-native/Libraries/Types/CodegenTypes';

/**
* The native surface. Codegen turns this into the Java and ObjC++ specs.
Expand Down Expand Up @@ -29,8 +31,8 @@ export interface Spec extends TurboModule {
*/
setAppearanceColor(name: string, r: number, g: number, b: number, a: number): void;

readonly onNewMessagesReceived: EventEmitter<{ messagesJson: string }>;
readonly onNewMessageSent: EventEmitter<{ message: string }>;
readonly onNewMessagesReceived: CodegenTypes.EventEmitter<{ messagesJson: string }>;
readonly onNewMessageSent: CodegenTypes.EventEmitter<{ message: string }>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('BugseeFeedbackModule');
27 changes: 22 additions & 5 deletions packages/react-native/BugseeReactNative.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
require 'json'

package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
native = JSON.parse(File.read(File.join(__dir__, '..', '..', 'native-versions.json')))
# The one source of every native pin. In this repo it is the root file. In an
# app the package sits in node_modules, where the root file is not above it, so
# prepack ships a copy at the package root (scripts/pack-native-versions.ts);
# that copy is read first.
native_versions_file = [
File.join(__dir__, 'native-versions.json'),
File.join(__dir__, '..', '..', 'native-versions.json'),
].find { |path| File.file?(path) }
raise "native-versions.json not found in #{__dir__} or the repo root above it" unless native_versions_file
native = JSON.parse(File.read(native_versions_file))

Pod::Spec.new do |s|
s.name = 'BugseeReactNative'
Expand Down Expand Up @@ -51,16 +60,24 @@ Pod::Spec.new do |s|
VERSION="#{native['ios']['sdk']}"
STAMP=".bugsee-xcframework-version"
if [ ! -d "Bugsee.xcframework" ] || [ "$(cat "${STAMP}" 2>/dev/null)" != "${VERSION}" ]; then
rm -rf "Bugsee.xcframework"
curl -sSfL -o /tmp/Bugsee-${VERSION}.zip \
# A download directory of this run's own. A fixed /tmp path is shared by
# every pod install on the machine: two at once overwrote and deleted
# each other's archive mid-extract ("bad CRC").
WORK="$(mktemp -d "${TMPDIR:-/tmp}/bugsee-xcframework.XXXXXX")"
# Unpacked beside its destination, so the final mv is a rename on one
# filesystem: a failed download or extract leaves nothing half-written.
STAGE="$(mktemp -d "./.bugsee-xcframework.XXXXXX")"
trap 'rm -rf "${WORK}" "${STAGE}"' EXIT
curl -sSfL -o "${WORK}/Bugsee.zip" \
"https://download.bugsee.com/sdk/ios/spm/Bugsee-${VERSION}.zip"
# Only the framework. The archive also carries the iOS SDK's own
# README.md and LICENSE at its root, and extracting everything drops
# them into this package -- where npm publishes README.md and LICENSE
# whatever `files` says. That is how this package came to ship the SDK's
# CocoaPods instructions and PLCrashReporter's licence.
unzip -q -o /tmp/Bugsee-${VERSION}.zip 'Bugsee.xcframework/*' -d .
rm -f /tmp/Bugsee-${VERSION}.zip
unzip -q -o "${WORK}/Bugsee.zip" 'Bugsee.xcframework/*' -d "${STAGE}"
rm -rf "Bugsee.xcframework"
mv "${STAGE}/Bugsee.xcframework" "Bugsee.xcframework"
printf '%s' "${VERSION}" > "${STAMP}"
fi
CMD
Expand Down
Loading
Loading