基于 React Native Template Obytes 模板,集成 cnb.cool CI 流水线,打 Tag 即可自动构建 Android APK。
本项目基于 Obytes React Native Template —— 一个生产级的 React Native 开发模板,核心技术栈:
| 分类 | 技术 |
|---|---|
| 框架 | Expo SDK 54 + React Native 0.81 |
| 语言 | TypeScript(严格模式) |
| 路由 | Expo Router 6(文件路由) |
| 样式 | TailwindCSS (Uniwind) |
| 数据 | React Query + Axios |
| 表单 | TanStack Form + Zod |
| 状态 | Zustand |
| 存储 | react-native-mmkv |
| 国际化 | i18next |
| 测试 | Jest + React Testing Library |
模板内置了认证流程、Feed 列表、设置页、多主题、多语言等示例模块,开箱即用。
详细的开发指南请查看 DEVELOPMENT-GUIDE.md
本仓库配置了 .cnb.yml,支持在 cnb.cool 平台上通过 打 Tag 自动构建 Android APK 并发布到 Release。
git tag v1.0.0 && git push origin v1.0.0 │ ▼ CNB 检测 tag_push 事件 │ ▼ 从 Tag 提取版本号 (v1.0.0 → 1.0.0) │ ▼ 安装依赖 → 注入版本号 → EAS 本地构建 │ ▼ 生成 APK → 创建 Release → 上传附件 │ ▼ ✅ 在 Release 页面下载 app-1.0.0.apk
按以下步骤配置,即可使用本仓库自动构建 Android APK。
在 cnb.cool 上 Fork 本仓库,或创建新仓库并推送代码。
访问 expo.dev 注册账号(如已有账号则登录)
创建 Expo 项目:在项目根目录运行以下命令(或在 Expo 网站创建):
npm install -g eas-cli
eas login # 登录你的 Expo 账号
eas init # 初始化项目,会返回 Project ID
获取 EXPO_TOKEN:访问 expo.dev/settings/access-tokens,创建一个 Personal Access Token,记录下来备用。
记录以下三个值:
| 值 | 来源 | 示例 |
|---|---|---|
| Expo 用户名 | eas whoami | hakureireimi |
| Project ID | eas init 返回 / Expo 项目设置页 | a9a3f80e-aaff-4d52-... |
| Project Slug | Expo 项目设置页 | test-cnb |
编辑 app.config.ts,将以下三处替换为你自己的值:
// app.config.ts 第 11-12 行
const EXPO_ACCOUNT_OWNER = 'your-expo-username'; // ← 改为你的 Expo 用户名
const EAS_PROJECT_ID = 'your-project-id'; // ← 改为你的 Project ID
// app.config.ts 第 36 行
slug: 'your-project-slug', // ← 改为你的 Project Slug
这三个值是公开信息,直接写在代码中即可,不需要放入秘钥仓库。
CNB 使用「秘钥仓库」管理敏感信息,这是一种高安全等级的特殊仓库,禁止 clone,只能通过 Web 编辑。
your-org/secrets)env.yml,写入以下内容:# 访问控制:只允许指定仓库引用此秘钥
allow_slugs:
- your-org/your-repo-name # ← 改为你的 CNB 仓库路径
# 只允许 tag_push 事件使用
allow_events:
- tag_push
# Expo 访问令牌(第 2 步获取的 Token)
EXPO_TOKEN: "your-expo-access-token" # ← 改为你的 EXPO_TOKEN
编辑 .cnb.yml,将 imports 中的 URL 替换为你的秘钥仓库文件地址:
imports:
- https://cnb.cool/your-org/secrets/-/blob/main/env.yml # ← 改为你的实际地址
git add -A
git commit -m "chore: 配置 Expo 项目和 CNB CI"
git push origin master
# 打 Tag(Tag 名称即版本号,必须以 v 开头)
git tag v1.0.0
git push origin v1.0.0
推送后,cnb.cool 会自动开始构建。在仓库的「构建」页面可查看实时日志。
构建完成后,在仓库的 Releases 页面即可下载 app-1.0.0.apk。
v*: # 匹配所有 v 开头的 tag
tag_push: # tag 推送事件触发
- name: android-apk-build
runner:
cpus: 32 # 构建节点 CPU 数
docker:
image: reactnativecommunity/react-native-android:latest # 含 Android SDK 的镜像
imports: # 从秘钥仓库导入 EXPO_TOKEN
- https://cnb.cool/.../env.yml
env: # 环境变量
EXPO_PUBLIC_APP_ENV: preview
GRADLE_OPTS: "..." # Gradle 内存限制
NODE_OPTIONS: "..." # Node 内存限制
stages:
- name: 环境准备 # 打印 Tag 信息、检查环境
- name: 安装依赖 # pnpm install + eas-cli
- name: 构建 APK # 注入版本号 → eas build --local
- name: 发布 Release # 创建 Release + 上传 APK
关键环境变量:
| 变量 | 来源 | 用途 |
|---|---|---|
EXPO_TOKEN | 秘钥仓库(imports) | EAS CLI 认证 |
EXPO_PUBLIC_APP_ENV | .cnb.yml 的 env | 构建环境(preview/production) |
CNB_BRANCH | CNB 内置变量 | Tag 名称,用作版本号 |
GRADLE_OPTS | .cnb.yml 的 env | 限制 Gradle JVM 内存防 OOM |
NODE_OPTIONS | .cnb.yml 的 env | 限制 Node.js 内存防 OOM |
Tag 命名规范:
| 格式 | 示例 | 说明 |
|---|---|---|
v{x}.{y}.{z} | v1.0.0 | 正式版本 |
v{x}.{y}.{z}-beta.{n} | v2.0.0-beta.1 | Beta 测试版 |
v{x}.{y}.{z}-rc.{n} | v1.5.0-rc.2 | Release Candidate |
Tag 必须以
v开头才会触发构建,非v开头的 Tag 会被跳过。
Q: 构建报权限错误(Entity not authorized)
A: app.config.ts 中的 EXPO_ACCOUNT_OWNER、EAS_PROJECT_ID、slug 必须与你的 Expo 项目匹配。
Q: 构建被 OOM 杀掉(signal: 9)
A: 调整 .cnb.yml 中的 GRADLE_OPTS 和 NODE_OPTIONS 内存限制,以及 metro.config.js 中的 maxWorkers。
Q: EXPO_TOKEN 未读取到
A: 检查秘钥仓库中 env.yml 的 allow_slugs 是否包含你的仓库路径,allow_events 是否包含 tag_push。
Q: slug does not match
A: app.config.ts 中的 slug 必须与 Expo 项目的 slug 完全一致。
This project is MIT licensed.