Skip to content

Commit 8d77854

Browse files
author
DooPush Bot
committed
Sync from main repository - 2026-05-07 09:46:02
1 parent efa4db5 commit 8d77854

3 files changed

Lines changed: 193 additions & 51 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
name: Auto Publish Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch: # 允许手动触发
8+
9+
jobs:
10+
publish:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write # 允许创建标签和 GitHub Release
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0 # 拿完整历史,便于 tag 检查
20+
21+
- name: Read package version
22+
id: version
23+
run: |
24+
VERSION=$(node -p "require('./package.json').version")
25+
if [ -z "$VERSION" ] || [ "$VERSION" = "undefined" ]; then
26+
echo "❌ 未在 package.json 中找到 version"
27+
exit 1
28+
fi
29+
echo "📦 检测到版本: $VERSION"
30+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
31+
echo "tag=v$VERSION" >> "$GITHUB_OUTPUT"
32+
33+
# 判断 alpha / beta / rc / latest
34+
if [[ "$VERSION" == *"-alpha"* ]] || [[ "$VERSION" =~ ^0\.[0-4]\. ]]; then
35+
DIST_TAG="alpha"
36+
elif [[ "$VERSION" == *"-beta"* ]] || [[ "$VERSION" =~ ^0\.[5-9]\. ]]; then
37+
DIST_TAG="beta"
38+
elif [[ "$VERSION" == *"-rc"* ]]; then
39+
DIST_TAG="rc"
40+
else
41+
DIST_TAG="latest"
42+
fi
43+
echo "🏷️ npm dist-tag: $DIST_TAG"
44+
echo "dist_tag=$DIST_TAG" >> "$GITHUB_OUTPUT"
45+
46+
- name: Check if git tag already exists
47+
id: check
48+
run: |
49+
if git ls-remote --tags origin "refs/tags/${{ steps.version.outputs.tag }}" | grep -q "${{ steps.version.outputs.tag }}"; then
50+
echo "ℹ️ tag ${{ steps.version.outputs.tag }} 已存在,跳过发布"
51+
echo "exists=true" >> "$GITHUB_OUTPUT"
52+
else
53+
echo "✅ tag 不存在,准备发布"
54+
echo "exists=false" >> "$GITHUB_OUTPUT"
55+
fi
56+
57+
- name: Setup pnpm
58+
if: steps.check.outputs.exists == 'false'
59+
uses: pnpm/action-setup@v4
60+
with:
61+
version: 9
62+
63+
- name: Setup Node
64+
if: steps.check.outputs.exists == 'false'
65+
uses: actions/setup-node@v4
66+
with:
67+
node-version: 20
68+
cache: pnpm
69+
registry-url: 'https://registry.npmjs.org'
70+
71+
- name: Install dependencies
72+
if: steps.check.outputs.exists == 'false'
73+
run: pnpm install --frozen-lockfile
74+
75+
- name: Build
76+
if: steps.check.outputs.exists == 'false'
77+
run: pnpm build
78+
79+
- name: Test
80+
if: steps.check.outputs.exists == 'false'
81+
run: pnpm test
82+
83+
- name: Configure Git
84+
if: steps.check.outputs.exists == 'false'
85+
run: |
86+
git config --global user.name "DooPush Bot"
87+
git config --global user.email "bot@doopush.com"
88+
89+
- name: Create and push git tag
90+
if: steps.check.outputs.exists == 'false'
91+
run: |
92+
git tag ${{ steps.version.outputs.tag }}
93+
git push origin ${{ steps.version.outputs.tag }}
94+
95+
- name: Create GitHub Release
96+
if: steps.check.outputs.exists == 'false'
97+
uses: softprops/action-gh-release@v2
98+
with:
99+
tag_name: ${{ steps.version.outputs.tag }}
100+
name: ${{ steps.version.outputs.tag }}
101+
generate_release_notes: true
102+
prerelease: ${{ steps.version.outputs.dist_tag != 'latest' }}
103+
body: |
104+
See [CHANGELOG](https://github.com/doopush/doopush-react-native-sdk/blob/main/README.md#changelog) for details.
105+
106+
**Install via npm:**
107+
```bash
108+
npm install doopush-react-native-sdk@${{ steps.version.outputs.version }}
109+
# 或 (alpha/beta 阶段)
110+
npm install doopush-react-native-sdk@${{ steps.version.outputs.dist_tag }}
111+
```
112+
env:
113+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
114+
115+
- name: Publish to npm
116+
if: steps.check.outputs.exists == 'false'
117+
run: |
118+
# --no-git-checks: pnpm 默认要求工作树干净 + 在跟随分支
119+
# --access public: 默认公开包(doopush-react-native-sdk 不带 scope)
120+
# --tag: alpha / beta / rc / latest,由版本号自动推断
121+
pnpm publish --no-git-checks --access public --tag ${{ steps.version.outputs.dist_tag }}
122+
env:
123+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ build/
33
plugin/build/
44
*.log
55
.DS_Store
6-
example/ios
7-
example/android
8-
example/.expo
9-
example/google-services.json
6+
7+
# Gradle build cache (Android subproject is consumed via JitPack/maven, source-only here)
8+
android/.gradle/
9+
android/build/
10+
android/.idea/
11+
android/local.properties
12+
*.iml

README.md

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,49 @@
11
# DooPush React Native SDK
22

3-
> **v0.1.0 alpha** Minimal API surface for end-to-end validation.
4-
> FCM (Android) + APNs (iOS) only. OEM channels and React Hooks coming in v0.5.0 beta.
3+
> **v0.1.1 alpha**— 最小 API surface,端到端真实可用。
4+
> 仅支持 FCM (Android) + APNs (iOS)OEM 通道、React Hooks v0.5.0 beta
55
6-
React Native SDK for [DooPush](https://doopush.com) push notification service. Built with Expo Modules API; works in Expo (managed / prebuild) and bare React Native.
6+
[DooPush](https://doopush.com) 推送通知服务的 React Native SDK。基于 Expo Modules API 实现,可在 Expomanaged / prebuild)和 bare React Native 项目里使用。
77

8-
## What's in v0.1.0 alpha
8+
## v0.1.x alpha 提供什么
99

1010
-`DooPush.configure(config)`
11-
-`DooPush.register()` APNs (iOS) / FCM (Android) auto flow
12-
-`DooPush.registerWithToken(token, vendor)` for callers with a token already
13-
- 🟡 `DooPush.getDeviceToken()` / `getDeviceId()` both return `null` in v0.1.0 (native getters not yet exposed; arrives in v0.5.0)
14-
-Event listeners: `addRegisterListener`, `addRegisterErrorListener`, `addMessageListener`
15-
- ✅ Config plugin: FCM vendor (google-services.json), iOS entitlements
16-
-Active mode (Android): DooPush owns notification UI; coexistence with `expo-notifications` via broadcast relay (opt-in, JS bridge in v0.5.0)
11+
-`DooPush.register()`iOS APNs / Android FCM 自动流程
12+
-`DooPush.registerWithToken(token, vendor)`— 调用方已经有 token 时(如配合 expo-notifications 共存)
13+
- 🟡 `DooPush.getDeviceToken()` / `getDeviceId()`— 当前都返回 `null`,原生 getter 还没暴露,v0.5.0 上线
14+
-事件监听:`addRegisterListener``addRegisterErrorListener``addMessageListener`
15+
- ✅ Config 插件:FCM 厂商(google-services.json)、iOS entitlement
16+
- ✅ Android Active 模式:DooPush 接管通知 UI;与 `expo-notifications` 通过广播 relay 共存(opt-inJS bridge v0.5.0
1717

18-
### Known v0.1 limitations
18+
### v0.1 已知限制
1919

20-
- `register()` resolves `{token, deviceId, vendor}` but `deviceId` is currently the empty string on Android (server-side deviceId not yet captured by the bridge — wired up in v0.5.0). The `token` and `vendor` fields are correct.
21-
- `getDeviceToken()` / `getDeviceId()` always return `null` on Android (no public getter on the underlying SDK yet).
20+
- `register()` 返回 `{token, deviceId, vendor}`,但 Android 端 `deviceId` 当前是空字符串(服务端 deviceId 还没在 bridge 层捕获,v0.5.0 修)。`token` `vendor` 字段是对的。
21+
- `getDeviceToken()` / `getDeviceId()` 在 Android 上一直返回 `null`(底层 SDK 还没公开 getter)。
2222

23-
## Not in v0.1.0 (coming in v0.5.0+)
23+
## v0.1 不包含(v0.5.0+ 才有)
2424

25-
- React hooks (`useDooPush`, `useDooPushToken`)
26-
- OEM vendors (HMS / Honor / Xiaomi / OPPO / VIVO / Meizu)
27-
- WebSocket gateway JS API
28-
- Statistics / badge / channel JS API
29-
- npm publication (use git tag for now)
25+
- React Hooks(`useDooPush``useDooPushToken`
26+
- OEM 通道(HMS / Honor / Xiaomi / OPPO / VIVO / Meizu
27+
- WebSocket gateway JS API
28+
- 统计 / 角标 / 通道相关的 JS API
29+
- npm 发布(当前用 git tag
3030

31-
## Prerequisites
31+
## 前置条件
3232

33-
- iOS native SDK ≥ 1.1.0 (SPM tag `v1.1.0` of `doopush-ios-sdk`, OR path-based dev dependency)
34-
- Android native SDK ≥ 1.1.0 (JitPack `com.github.doopush:doopush-android-sdk:v1.1.0`, OR mavenLocal)
35-
- Expo SDK 50+ (or RN 0.73+ bare)
33+
- iOS 原生 SDK ≥ **1.1.1**SPM tag `v1.1.1` of `doopush-ios-sdk`,或路径方式本地引用)
34+
- Android 原生 SDK ≥ **1.1.0**JitPack `com.github.doopush:doopush-android-sdk:v1.1.0`,或本地 mavenLocal
35+
- Expo SDK 50+(或 RN 0.73+ bare)。**新项目推荐 Expo SDK 54+**
3636

37-
## Quick install (once published)
37+
## 快速安装(公开发布后)
3838

3939
```bash
4040
npx expo install doopush-react-native-sdk
4141
```
4242

43-
In `app.json`:
43+
> v0.1.x alpha **暂未发到 npm**,公开仓走 git tag:
44+
> `npm install github:doopush/doopush-react-native-sdk#v0.1.1`
45+
46+
`app.json` 配 plugin:
4447

4548
```json
4649
{
@@ -67,10 +70,10 @@ In `app.json`:
6770

6871
```bash
6972
npx expo prebuild --clean
70-
npx expo run:android # or run:ios
73+
npx expo run:android # run:ios
7174
```
7275

73-
## Usage
76+
## 用法
7477

7578
```tsx
7679
import { useEffect, useState } from 'react';
@@ -83,58 +86,70 @@ export default function App() {
8386
apiKey: 'your_api_key',
8487
});
8588
const sub = DooPush.addMessageListener((m: DooPushMessage) => {
86-
console.log('push received', m);
89+
console.log('收到推送', m);
8790
});
8891
return () => sub.remove();
8992
}, []);
9093

9194
const handleRegister = async () => {
9295
try {
9396
const { token, deviceId } = await DooPush.register();
94-
console.log('registered', token, deviceId);
97+
console.log('注册成功', token, deviceId);
9598
} catch (e) {
96-
console.error('register failed', e);
99+
console.error('注册失败', e);
97100
}
98101
};
99102

100103
// ...
101104
}
102105
```
103106

104-
## Local development
107+
## 本地开发
105108

106-
This package is part of the [doopush monorepo](https://github.com/doopush/doopush). To develop:
109+
本包是 [doopush monorepo](https://github.com/doopush/doopush) 的一部分,跟 iOS / Android 原生 SDK 平级。本地开发流程:
107110

108111
```bash
109-
# 1) Build the SDK
112+
# 1) 编译 SDK
110113
cd sdk/react-native/DooPushSDK
111114
pnpm install
112115
pnpm build
113-
pnpm test # plugin Jest tests
116+
pnpm test # plugin Jest 测试
114117

115-
# 2) Use the sibling demo app
118+
# 2) 用同级的 demo app 验证
116119
cd ../DooPushSDKExample
117120
npm install
118-
npm install file:../DooPushSDK --install-links # copy SDK (avoid symlink so Metro resolves)
119-
npx expo run:ios # iOS sim or --device "<device name>"
120-
npx expo run:android # Android emulator or --device <id>
121+
npm install file:../DooPushSDK --install-links # 用拷贝替代 symlink,避开 Metro 解析坑
122+
npx expo run:ios # 模拟器,或 --device "<设备名>"
123+
npx expo run:android # 模拟器,或 --device <id>
121124
```
122125

123-
The demo lives at `sdk/react-native/DooPushSDKExample/` (peer of the SDK, not nested), keeping the same shape as the iOS / Android native examples in this monorepo.
126+
详细的真机跑步骤、故障排查、Mac LAN IP 注入等见 `../DooPushSDKExample/README.md`
127+
128+
仓库结构跟 iOS / Android SDK 对齐:
129+
130+
```
131+
sdk/react-native/
132+
├── DooPushSDK/ ← SDK 源(npm 包 doopush-react-native-sdk)
133+
│ ├── src/ # JS API 层
134+
│ ├── plugin/ # Expo config plugin(编译期 native 配置注入)
135+
│ ├── ios/ # iOS 原生 bridge + AppDelegate subscriber
136+
│ └── android/ # Android 原生 bridge
137+
└── DooPushSDKExample/ ← 用 SDK 的 demo(与 iOS/Android example 平级)
138+
```
124139

125-
## Coexistence
140+
## 与第三方共存
126141

127-
### With `expo-notifications`
142+
### `expo-notifications`
128143

129-
Compatible by default. DooPush owns `UNUserNotificationCenterDelegate` (iOS) but uses delegate-forwarding to keep `expo-notifications` listeners working. On Android, DooPush owns `FirebaseMessagingService`; if you need `expo-notifications` to also receive FCM messages, call (in v0.5.0+):
144+
默认兼容。iOS 上 DooPush 接管 `UNUserNotificationCenterDelegate` 但走 delegate-forwarding`expo-notifications` 的监听依然能收到。AndroidDooPush 接管 `FirebaseMessagingService`,如果你也想让 `expo-notifications` 收到 FCM 消息,调(v0.5.0+):
130145

131146
```ts
132147
DooPush.setExpoNotificationRelayEnabled(true);
133148
```
134149

135-
### With `@react-native-firebase/messaging`
150+
### `@react-native-firebase/messaging`
136151

137-
**Choose one** both libraries declare `FirebaseMessagingService` and only one wins manifest merger. If you already use `react-native-firebase`, omit the FCM vendor from the DooPush plugin and use `react-native-firebase`'s token API:
152+
**二选一**— 两个库都声明 `FirebaseMessagingService`manifest merger 只能留一个。如果你已经在用 `react-native-firebase`,就在 DooPush plugin **省略 fcm 厂商**,用 `react-native-firebase`token 后再交给 DooPush:
138153

139154
```ts
140155
import messaging from '@react-native-firebase/messaging';
@@ -151,8 +166,9 @@ MIT
151166
## CHANGELOG
152167

153168
### v0.1.1
154-
- **Fix (iOS)**: Forward APNs delegate callbacks via `ExpoAppDelegateSubscriber`. Without this, on Expo apps the device token never reached `DooPushManager.shared.didRegisterForRemoteNotifications(with:)` and `DooPush.register()` hung forever after the user granted permission. Adds `DooPushAppDelegateSubscriber` registered in `expo-module.config.json`.
155-
- **Repo hygiene**: removed nested `DooPushSDK/example/` workspace; the demo lives at `sdk/react-native/DooPushSDKExample/` (peer of the SDK), aligning with the iOS / Android example layout.
169+
- **修复 (iOS)**:通过 `ExpoAppDelegateSubscriber` 转发 APNs delegate 回调。在此之前,Expo 应用里 AppDelegate 拿到 device token 后没通路回 `DooPushManager.shared.didRegisterForRemoteNotifications(with:)`,导致 `DooPush.register()` 在用户授权后**永远 hang**。新增 `DooPushAppDelegateSubscriber`,并在 `expo-module.config.json` 里注册(autolinking 把它写进 `ExpoModulesProvider`)。同时转发 `didFailToRegister``didReceiveRemoteNotification:fetchCompletionHandler:`
170+
- **依赖底座**:iOS 原生 SDK 升级到 v1.1.1(podspec 兼容性修复,移除自定义 module_map / 不存在的 LICENSE 引用 / 多余的 public_header_files)。
171+
- **结构整理**:删除嵌套的 `DooPushSDK/example/` workspace,demo 移到同级的 `sdk/react-native/DooPushSDKExample/`,跟 iOS/Android example 对齐。
156172

157173
### v0.1.0
158-
- Initial alpha. `configure`, `register`, `registerWithToken`, message / register listeners. iOS APNs (active mode) + Android FCM only. Config plugin with FCM google-services injection.
174+
- 首个 alpha`configure``register``registerWithToken`、消息 / 注册监听器。仅 iOS APNsactive 模式)+ Android FCMConfig plugin 注入 FCM google-services

0 commit comments

Comments
 (0)