Skip to content

fix(amplitude) + feat: recover lastEventTime & add branch releases#1198

Open
abueide wants to merge 17 commits into
masterfrom
fix/ios-zero-second-sessions
Open

fix(amplitude) + feat: recover lastEventTime & add branch releases#1198
abueide wants to merge 17 commits into
masterfrom
fix/ios-zero-second-sessions

Conversation

@abueide
Copy link
Copy Markdown
Contributor

@abueide abueide commented Apr 7, 2026

Summary

Fixes 0-second sessions in Amplitude Session plugin on iOS when Background Fetch is enabled, and implements branch-specific prerelease channels for better semantic versioning.

Changes

Amplitude Session Fix

  • Add recovery logic in startNewSessionIfNecessary() for partial AsyncStorage persistence
  • Recover lastEventTime from sessionId when lastEventTime === -1 but sessionId >= 0
  • Remove lastEventTime === -1 from isSessionExpired check (now handled by recovery)
  • Remove incorrect 1-second timestamp guard from onForeground()
  • Add 8 hypothesis-driven tests for 0-second session reproduction

Branch-Specific Prerelease Channels

  • Update release.config.js with per-branch channels: fix/*-fix.N, feat/*-feat.N, beta-beta.N
  • Add Publish-Prerelease GitHub environment
  • Rename workflow input from beta to prerelease
  • Add PRERELEASE_SETUP.md documentation

Why

Session fix: Plugin persists sessionId and lastEventTime via independent fire-and-forget writes. If app is killed mid-persist (common during iOS Background Fetch), lastEventTime may be lost while sessionId survives, falsely triggering session expiration on next launch.

Prerelease channels: Allows distributing fixes and features independently (npm install @segment/analytics-react-native@fix) without polluting the beta channel.


🤖 Generated with Claude Code

@abueide abueide changed the title fix(amplitude-session): prevent 0-second sessions from iOS Background Fetch fix(amplitude-session): recover lastEventTime on partial persist Apr 7, 2026
@abueide abueide added bug Bug fix review-needed needs-review Ready for review and removed review-needed labels Apr 9, 2026
@abueide abueide self-assigned this Apr 13, 2026
@abueide abueide force-pushed the fix/ios-zero-second-sessions branch from 6872c0c to 41a5d02 Compare April 15, 2026 19:41
abueide and others added 3 commits April 15, 2026 15:07
… Fetch

iOS Background Fetch can briefly trigger AppState 'active' without user
interaction, causing rapid session creation/destruction cycles. Add a
1-second timestamp guard in onForeground() to prevent new sessions from
starting within 1 second of the last session creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace incorrect 1-second timestamp guard with proper root cause fix.

The 0-second session bug is caused by non-atomic AsyncStorage persistence:
when the app is killed (e.g. during iOS Background Fetch), sessionId may
persist while lastEventTime does not. On relaunch, lastEventTime === -1
with a valid sessionId falsely triggers session expiration, ending the
just-created session immediately.

The fix recovers lastEventTime from sessionId when partial persistence
is detected, preventing the false expiration. Also adds hypothesis-driven
reproduction tests that verify the fix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix CI formatting check failures.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
abueide and others added 4 commits April 15, 2026 21:43
Changed from a single "beta" prerelease channel to branch-specific
channels:
- fix/* → x.x.x-fix.N
- feat/* → x.x.x-feat.N
- chore/* → x.x.x-chore.N
- beta → x.x.x-beta.N (explicit)

This provides better semantic meaning for prerelease versions. Instead
of all non-master branches being "beta", each category gets its own
channel.

Examples:
- fix/ios-zero-second-sessions → 2.22.1-fix.1
- feat/new-feature → 2.22.1-feat.1
- beta → 2.22.1-beta.1

Updated workflow to use new "Publish-Prerelease" environment instead
of "Publish-Beta" to reflect the broader scope.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added comprehensive documentation for the new branch-specific prerelease
system including:
- GitHub environment setup instructions
- npm token vs OIDC setup options
- Testing and verification steps
- Troubleshooting guide
- Migration notes from old beta setup

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Removed chore/* branches from prerelease channels since they're for
internal changes not meant for client distribution. Only fix/* and
feat/* branches (plus explicit beta) will publish now.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed the workflow input from 'beta' to 'prerelease' to avoid
confusion. The input triggers prerelease publishing for any prerelease
channel (fix, feat, or beta), not just the beta channel.

Now you select:
- dry-run → test without publishing
- prerelease → publish fix/feat/beta channels
- production → production release from main

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@abueide abueide changed the title fix(amplitude-session): recover lastEventTime on partial persist fix(amplitude-session) + feat: prerelease channels - recover lastEventTime & implement branch-specific releases Apr 16, 2026
@abueide abueide temporarily deployed to Publish-Prerelease April 16, 2026 03:12 — with GitHub Actions Inactive
@sunitaprajapati89 sunitaprajapati89 deployed to Publish-Prerelease April 21, 2026 10:32 — with GitHub Actions Active
@sunitaprajapati89 sunitaprajapati89 changed the title fix(amplitude-session) + feat: prerelease channels - recover lastEventTime & implement branch-specific releases fix(amplitude) + feat: recover lastEventTime & add branch releases Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Bug fix needs-review Ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants