Skip to content

Commit 791aef5

Browse files
authored
Merge branch 'main' into alwx/experiment/eas-build
2 parents d8aed6e + 5a14e8e commit 791aef5

File tree

38 files changed

+502
-141
lines changed

38 files changed

+502
-141
lines changed

.cursor/BUGBOT.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# PR Review Guidelines for Cursor Bot
2+
3+
**Scope & intent**
4+
5+
- High-level review guidance for the entire Sentry React Native SDK monorepo.
6+
- Optimize for **signal over noise**: only comment when there's material correctness, security/privacy, performance, or API-quality impact.
7+
- If you find anything to flag, mention that you flagged this in the review because it was mentioned in this rules file.
8+
- Do not flag the issues below if they appear only in tests.
9+
10+
**Reviewer style**
11+
12+
- Be concise. Quote exact lines/spans and propose a minimal fix (tiny diff/code block).
13+
- If something is subjective, ask a brief question rather than asserting.
14+
- Prefer principles over nitpicks; avoid noisy style-only comments that don't impact behavior.
15+
16+
---
17+
18+
## 0) Critical Issues to Flag
19+
20+
> Use a clear prefix like **CRITICAL:** in the review comment title.
21+
22+
### A. Security & Privacy
23+
24+
- **Secrets / credentials exposure**: Keys, tokens, DSNs, endpoints, or auth data in code, logs, tests, configs, or example apps.
25+
- **PII handling**: New code that logs or sends user-identifiable data without clear intent and controls. These must be gated behind the `sendDefaultPii` flag.
26+
- **Unsafe logging**: Request/response bodies, full URLs with query secrets, file paths or device identifiers logged by default.
27+
- **File/attachments**: Large or sensitive payloads attached by default; lack of size limits or backoff.
28+
- **Debug code shipped**: Diagnostics, sampling overrides, verbose logging, or feature flags accidentally enabled in production defaults.
29+
30+
### B. Public API & Stability
31+
32+
- **Breaking changes**: Signature/behavior changes, renamed/removed symbols, altered nullability/defaults, or event/telemetry shape changes **without** deprecation/migration notes.
33+
- **Behavioral compatibility**: Silent changes to defaults, sampling, or feature toggles that affect existing apps.
34+
- **Native bridge compatibility**: Changes to native module method signatures (iOS `RCT_EXPORT_METHOD` / Android `@ReactMethod`) must be backward-compatible or versioned, as they affect all consumers including Expo and bare React Native apps.
35+
36+
### C. Dependency Updates
37+
38+
- **Native SDK updates**: For PRs prefixed with `chore(deps):` updating native SDKs (e.g., `chore(deps): bump sentry-cocoa to v9.x.x`, `chore(deps): bump sentry-android to v8.x.x`):
39+
- Read the PR description which should contain the changelog.
40+
- Review mentioned changes for potential compatibility issues in the current codebase.
41+
- Flag breaking API changes, deprecated features being removed, new requirements, or behavioral changes that could affect existing integrations.
42+
- Check if version bumps require corresponding changes in the native bridge code (Objective-C/Swift on iOS, Java/Kotlin on Android).
43+
- **JavaScript dependency updates**: For PRs updating JS/TS dependencies, check for breaking API changes that affect the SDK's public surface or internal usage.
44+
45+
---
46+
47+
## 1) General Software Quality
48+
49+
**Clarity & simplicity**
50+
51+
- Prefer straightforward control flow, early returns, and focused functions.
52+
- Descriptive names; avoid unnecessary abbreviations.
53+
- Keep public APIs minimal and intentional.
54+
55+
**Correctness & safety**
56+
57+
- Add/update tests with behavioral changes and bug fixes.
58+
- Handle error paths explicitly; never let a Sentry instrumentation error crash the host app.
59+
- Avoid global mutable state; prefer immutability and clear ownership.
60+
61+
**DRY & cohesion**
62+
63+
- Remove duplication where it reduces complexity; avoid over-abstraction.
64+
- Keep modules cohesive; avoid reaching across layers for convenience.
65+
66+
**Performance (pragmatic)**
67+
68+
- Prefer linear-time approaches; avoid unnecessary allocations/copies.
69+
- Don't micro-optimize prematurely—call out obvious hotspots or regressions.
70+
- Be mindful of main-thread work in React Native; offload heavy work to native threads where possible.
71+
72+
---
73+
74+
## 2) TypeScript/JavaScript-Specific
75+
76+
**Idioms & language features**
77+
78+
- Use optional chaining (`?.`) and nullish coalescing (`??`) over manual null checks.
79+
- Avoid `any`; prefer `unknown` with explicit narrowing.
80+
- Use `async/await` over raw Promises for readability.
81+
- Follow the existing single-quote string style and 120-character line limit.
82+
83+
**Safety & async**
84+
85+
- Wrap `NativeModules` calls in try/catch; native bridges can throw.
86+
- Ensure Promises are handled; avoid unhandled rejections.
87+
- Check that `NativeModules.RNSentry` exists before calling methods (module may not be linked).
88+
89+
**Tree-shakeability**
90+
91+
- Avoid patterns that defeat tree shaking (e.g., side-effectful top-level code).
92+
- Use named exports; avoid re-exporting entire namespaces unnecessarily.
93+
- Instantiate optional integrations lazily (inside guarded branches).
94+
95+
---
96+
97+
## 3) React Native Bridge (Native Modules)
98+
99+
**iOS (Objective-C / Swift)**
100+
101+
- New `RCT_EXPORT_METHOD` / `RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD` must have a corresponding JS implementation.
102+
- Prefer `RCTPromiseResolveBlock`/`RCTPromiseRejectBlock` over synchronous returns for non-trivial work.
103+
- Wrap native calls in `@try/@catch` and reject the promise with a meaningful error code.
104+
- Nullability annotations (`nullable`/`nonnull`) must be consistent with JS-side expectations.
105+
- New Objective-C classes must use the `RNSentry` prefix.
106+
107+
**Android (Java / Kotlin)**
108+
109+
- New `@ReactMethod` entries must have a corresponding JS implementation.
110+
- Use `Promise` for async operations; call `promise.resolve()` or `promise.reject()` exactly once.
111+
- Avoid blocking the JS thread; offload heavy work to background threads.
112+
- Add `@Nullable` / `@NonNull` annotations consistently.
113+
- New classes must live under `io.sentry.react.*`.
114+
115+
**TurboModules / New Architecture**
116+
117+
- Changes to the native module spec (`NativeSentry.ts` or equivalent) must be reflected in both the legacy and new architecture implementations.
118+
- Verify that new methods are added to the codegen spec so they work with TurboModules.
119+
120+
---
121+
122+
## 4) SDK-Specific (high-level)
123+
124+
**Tracing & spans**
125+
126+
- Any span started must be **closed** (including on error paths).
127+
- For _automated_ instrumented spans, always set:
128+
- `sentry.origin`
129+
- `sentry.op` using a standard operation where applicable (see [Sentry's list of standard ops](https://develop.sentry.dev/sdk/telemetry/traces/span-operations/)).
130+
131+
**Structured logs**
132+
133+
- For _automated_ instrumented structured logs, always set `sentry.origin`.
134+
135+
**Initialization & error paths**
136+
137+
- Wrap dangerous or failure-prone paths (especially during `Sentry.init`) in `try/catch`, add actionable context, and ensure fallbacks keep the app usable.
138+
- Never let SDK initialization failure crash the host application.
139+
140+
**Replay & sensitive data**
141+
142+
- Any new UI instrumentation must respect the masking/unmasking API.
143+
- Default to masking sensitive views; opt-in to unmasking.
144+
145+
---
146+
147+
## Quick reviewer checklist
148+
149+
- [ ] **CRITICAL:** No secrets/PII/logging risks introduced; safe defaults preserved.
150+
- [ ] **CRITICAL:** Public API/telemetry stability maintained or properly deprecated with docs.
151+
- [ ] **CRITICAL:** For dependency updates (`chore(deps):`), changelog reviewed for breaking changes or compatibility issues.
152+
- [ ] Native bridge methods (iOS & Android) are consistent with JS-side calls and handle errors safely.
153+
- [ ] TurboModule/New Architecture spec updated if native module interface changed.
154+
- [ ] Spans started are always closed; automated spans/logs include `sentry.origin` (+ valid `sentry.op` for spans).
155+
- [ ] Dangerous init paths guarded; app remains usable on failure.
156+
- [ ] `NativeModules.RNSentry` existence checked before use; async bridge calls wrapped in try/catch.
157+
- [ ] Tests/docs/CHANGELOG updated for behavior changes.

.github/workflows/buildandtest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ jobs:
175175
name: ts3.8
176176
path: packages/core/ts3.8
177177
- name: Install Global Dependencies
178-
run: npm i -g add yalc
178+
run: npm i -g yalc
179179
- name: Type Check
180180
working-directory: dev-packages/type-check
181181
run: yarn type-check
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Cancel PR Workflows
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
jobs:
8+
cancel:
9+
name: Cancel In-Progress Workflows
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Cancel in-progress workflow runs
13+
uses: actions/github-script@v7
14+
with:
15+
script: |
16+
const { owner, repo } = context.repo;
17+
const branch = context.payload.pull_request.head.ref;
18+
19+
const workflows = await github.rest.actions.listWorkflowRunsForRepo({
20+
owner,
21+
repo,
22+
branch,
23+
status: 'in_progress',
24+
});
25+
26+
const waitingWorkflows = await github.rest.actions.listWorkflowRunsForRepo({
27+
owner,
28+
repo,
29+
branch,
30+
status: 'queued',
31+
});
32+
33+
const runs = [...workflows.data.workflow_runs, ...waitingWorkflows.data.workflow_runs];
34+
35+
for (const run of runs) {
36+
if (run.id === context.runId) {
37+
continue;
38+
}
39+
try {
40+
console.log(`Cancelling run ${run.id} (${run.name})`);
41+
await github.rest.actions.cancelWorkflowRun({
42+
owner,
43+
repo,
44+
run_id: run.id,
45+
});
46+
} catch (error) {
47+
console.log(`Failed to cancel run ${run.id}: ${error.message}`);
48+
}
49+
}
50+
51+
console.log(`Cancelled ${runs.length > 1 ? runs.length - 1 : 0} workflow run(s) for branch ${branch}`);

.github/workflows/changelog-preview.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ permissions:
1414

1515
jobs:
1616
changelog-preview:
17-
uses: getsentry/craft/.github/workflows/changelog-preview.yml@906009a1b771956757e521555b561379307eb667 # V2
17+
uses: getsentry/craft/.github/workflows/changelog-preview.yml@41defb379de52e5f0e3943944fa5575b22fb9f92 # V2
1818
secrets: inherit

.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444

4545
# Initializes the CodeQL tools for scanning.
4646
- name: Initialize CodeQL
47-
uses: github/codeql-action/init@9e907b5e64f6b83e7804b09294d44122997950d6 # pin@v4.32.3
47+
uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # pin@v4.32.4
4848
with:
4949
languages: ${{ matrix.language }}
5050
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -55,7 +55,7 @@ jobs:
5555
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
5656
# If this step fails, then you should remove it and run the build manually (see below)
5757
- name: Autobuild
58-
uses: github/codeql-action/autobuild@9e907b5e64f6b83e7804b09294d44122997950d6 # pin@v4.32.3
58+
uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e # pin@v4.32.4
5959

6060
# ℹ️ Command-line programs to run using the OS shell.
6161
# 📚 https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
@@ -66,4 +66,4 @@ jobs:
6666
# make bootstrap
6767
# make release
6868
- name: Perform CodeQL Analysis
69-
uses: github/codeql-action/analyze@9e907b5e64f6b83e7804b09294d44122997950d6 # pin@v4.32.3
69+
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # pin@v4.32.4

.github/workflows/e2e-v2.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ concurrency:
1414

1515
env:
1616
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
17-
MAESTRO_VERSION: '2.1.0'
17+
MAESTRO_VERSION: '2.2.0'
1818
IOS_DEVICE: 'iPhone 17'
1919
IOS_VERSION: '>=18.0'
2020

@@ -48,11 +48,11 @@ jobs:
4848
platform: ["ios", "android"]
4949
include:
5050
- platform: ios
51-
runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:12"]
51+
runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:10"]
5252
name: iOS
5353
appPlain: performance-tests/test-app-plain.ipa
5454
- platform: android
55-
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]
55+
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:10"]
5656
name: Android
5757
appPlain: performance-tests/TestAppPlain/android/app/build/outputs/apk/release/app-release.apk
5858
steps:
@@ -199,13 +199,13 @@ jobs:
199199
# Use Xcode 16 for older RN versions
200200
- platform: ios
201201
rn-version: '0.71.19'
202-
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:12"]
202+
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:10"]
203203
# Use Xcode 26 for newer RN versions (0.83.0)
204204
- platform: ios
205205
rn-version: '0.84.0'
206-
runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:12"]
206+
runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:10"]
207207
- platform: android
208-
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]
208+
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:10"]
209209
exclude:
210210
# exclude JSC for new RN versions (keeping the matrix manageable)
211211
- rn-version: '0.84.0'
@@ -334,7 +334,7 @@ jobs:
334334
rn-version: '0.84.0'
335335
runs-on: macos-26
336336
- platform: android
337-
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]
337+
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:10"]
338338

339339
steps:
340340
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
cache-dependency-path: yarn.lock
4444

4545
- name: Prepare release
46-
uses: getsentry/craft@906009a1b771956757e521555b561379307eb667 # v2
46+
uses: getsentry/craft@41defb379de52e5f0e3943944fa5575b22fb9f92 # v2
4747
env:
4848
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
4949
with:

.github/workflows/sample-application-expo.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ jobs:
4343
build-type: ['dev', 'production']
4444
include:
4545
- platform: ios
46-
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:12"]
46+
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:10"]
4747
- platform: android
48-
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]
48+
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:10"]
4949
- platform: web
50-
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]
50+
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:10"]
5151
exclude:
5252
- platform: 'android'
5353
ios-use-frameworks: 'dynamic-frameworks'

.github/workflows/sample-application.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ concurrency:
1313

1414
env:
1515
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
16-
MAESTRO_VERSION: '2.1.0'
16+
MAESTRO_VERSION: '2.2.0'
1717
MAESTRO_DRIVER_STARTUP_TIMEOUT: 90000 # Increase timeout from default 30s to 90s for CI stability
1818
RN_SENTRY_POD_NAME: RNSentry
1919
IOS_APP_ARCHIVE_PATH: sentry-react-native-sample.app.zip
@@ -52,11 +52,11 @@ jobs:
5252
build-type: ['dev', 'production']
5353
include:
5454
- platform: ios
55-
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:12"]
55+
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:10"]
5656
- platform: macos
57-
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:12"]
57+
runs-on: ["ghcr.io/cirruslabs/macos-sequoia-xcode:16.4", "runner_group_id:10"]
5858
- platform: android
59-
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:12"]
59+
runs-on: ["ghcr.io/cirruslabs/ubuntu-runner-amd64:22.04", "runner_group_id:10"]
6060
exclude:
6161
- platform: 'android'
6262
ios-use-frameworks: 'dynamic-frameworks'

.github/workflows/testflight.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515

1616
upload_to_testflight:
1717
name: Build and Upload React Native Sample to Testflight
18-
runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:12"]
18+
runs-on: ["ghcr.io/cirruslabs/macos-tahoe-xcode:26.2.0", "runner_group_id:10"]
1919
needs: [diff_check]
2020
if: ${{ needs.diff_check.outputs.skip_ci != 'true' }}
2121
steps:

0 commit comments

Comments
 (0)