Skip to content

Commit 7b9ac15

Browse files
committed
docs(workflow): add build and deploy guide for Operit APP
- Create comprehensive documentation for local and CI/CD build processes - Include setup instructions for JDK, Android SDK, and GitHub OAuth - Document APK build variants: debug, release, and nightly - Explain CI/CD workflows for automatic and manual builds - Provide troubleshooting tips and release checklist - Add links to related resources and external dependencies feat(ci): implement debug APK build workflow with GitHub Actions - Add new workflow to build debug APK on push/PR to main/dev/me branches - Support manual triggering via GitHub Actions UI - Automate setup of local.properties with GitHub secrets - Integrate Sherpa NCNN library and model extraction - Skip stripping of libsudo.so to prevent build errors - Fix deprecated manifest package attribute and C++ warnings - Upload debug APK as artifact with 30-day retention - Optionally publish debug builds as draft GitHub releases
1 parent db981ab commit 7b9ac15

2 files changed

Lines changed: 326 additions & 0 deletions

File tree

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
---
2+
description: 如何构建和部署 Operit APP
3+
---
4+
5+
# Operit 构建和部署指南
6+
7+
## 📋 前置条件
8+
9+
### 本地开发环境
10+
- JDK 17
11+
- Android SDK (API 26-34)
12+
- Android Studio (推荐)
13+
- Git
14+
15+
### CI/CD 环境
16+
- GitHub Repository Secrets 配置:
17+
- `GITHUB_CLIENT_ID`: GitHub OAuth App Client ID
18+
- `GITHUB_CLIENT_SECRET`: GitHub OAuth App Client Secret
19+
20+
---
21+
22+
## 🚀 本地构建流程
23+
24+
### 1. 克隆项目并初始化子模块
25+
```bash
26+
git clone https://github.com/AAswordman/Operit.git
27+
cd Operit
28+
git submodule update --init --recursive
29+
```
30+
31+
### 2. 配置本地环境
32+
```bash
33+
# 复制配置模板
34+
cp local.properties.example local.properties
35+
36+
# 编辑 local.properties,填入你的凭证
37+
# GITHUB_CLIENT_ID=你的ID
38+
# GITHUB_CLIENT_SECRET=你的SECRET
39+
```
40+
41+
### 3. 下载额外依赖
42+
[Google Drive](https://drive.google.com/drive/folders/1g-Q_i7cf6Ua4KX9ZM6V282EEZvTVVfF7) 下载依赖库,放置到 `app/libs/` 目录。
43+
44+
### 4. 构建 APK
45+
46+
#### Debug 版本
47+
```bash
48+
chmod +x gradlew
49+
./gradlew assembleDebug
50+
51+
# 输出位置: app/build/outputs/apk/debug/app-debug.apk
52+
```
53+
54+
#### Release 版本
55+
```bash
56+
./gradlew assembleRelease
57+
58+
# 输出位置: app/build/outputs/apk/release/app-release.apk
59+
```
60+
61+
#### Nightly 版本
62+
```bash
63+
./gradlew assembleNightly
64+
65+
# 输出位置: app/build/outputs/apk/nightly/app-nightly.apk
66+
```
67+
68+
### 5. 安装到设备
69+
```bash
70+
# 安装 Debug 版本
71+
./gradlew installDebug
72+
73+
# 或使用 adb
74+
adb install -r app/build/outputs/apk/debug/app-debug.apk
75+
```
76+
77+
---
78+
79+
## ⚙️ CI/CD 自动构建
80+
81+
### Debug 构建(新增)
82+
83+
**触发方式:**
84+
1. 推送到 `main`, `dev`, 或 `me` 分支
85+
2. 创建 Pull Request
86+
3. 手动触发(在 GitHub Actions 页面)
87+
88+
**产物获取:**
89+
- 进入 GitHub Actions 页面
90+
- 找到对应的 workflow run
91+
- 在 Artifacts 区域下载 `operit-debug-apk`
92+
93+
**手动触发步骤:**
94+
// turbo
95+
1. 打开仓库的 Actions 页面
96+
2. 选择 "Build Debug APK" workflow
97+
3. 点击 "Run workflow" 按钮
98+
4. 选择分支,点击绿色的 "Run workflow"
99+
100+
### Release 构建(已存在)
101+
102+
**触发方式:**
103+
1. 推送 tag(格式:`v*`,例如 `v1.6.3`
104+
2. 手动触发
105+
106+
**发布流程:**
107+
```bash
108+
# 创建并推送 tag
109+
git tag v1.6.3
110+
git push origin v1.6.3
111+
112+
# CI 会自动:
113+
# 1. 构建 Release APK
114+
# 2. 创建 GitHub Release
115+
# 3. 上传 APK 到 Release
116+
```
117+
118+
---
119+
120+
## 🔍 特殊配置说明
121+
122+
### 1. 签名配置
123+
项目使用 `app/release.keystore` 进行签名:
124+
- Store Password: `android`
125+
- Key Alias: `androiddebugkey`
126+
- Key Password: `android`
127+
128+
**注意:** 生产环境应使用更安全的密钥!
129+
130+
### 2. ABI 支持
131+
项目当前只构建 `arm64-v8a` 架构(见 `app/build.gradle.kts` line 50)
132+
133+
如需支持更多架构,修改:
134+
```kotlin
135+
ndk {
136+
abiFilters.addAll(listOf("arm64-v8a", "armeabi-v7a"))
137+
}
138+
```
139+
140+
### 3. 外部依赖
141+
CI 会自动下载以下内容:
142+
- **Sherpa NCNN**: 语音识别库和模型
143+
- 库文件: `app/src/main/jniLibs/arm64-v8a/`
144+
- 模型文件: `app/src/main/assets/models/`
145+
146+
### 4. 构建变体
147+
- **debug**: 开发调试版本
148+
- **release**: 正式发布版本(启用签名)
149+
- **nightly**: 每夜构建版本(与 release 类似)
150+
151+
---
152+
153+
## 🐛 常见问题
154+
155+
### Q: 构建失败 - libsudo.so stripping error
156+
**A:** CI 已配置跳过 libsudo.so 的符号剥离。如本地遇到此问题,在 `terminal/build.gradle.kts` 添加:
157+
```kotlin
158+
android {
159+
packaging {
160+
jniLibs {
161+
keepDebugSymbols.add("**/libsudo.so")
162+
}
163+
}
164+
}
165+
```
166+
167+
### Q: GitHub OAuth 配置问题
168+
**A:**
169+
1. 访问 https://github.com/settings/developers
170+
2. 创建新的 OAuth App
171+
3. Callback URL 设置为:`operit://github-oauth-callback`
172+
4. 将 Client ID 和 Secret 填入 `local.properties`
173+
174+
### Q: 依赖下载失败
175+
**A:**
176+
1. 检查网络连接
177+
2. 确保 Google Drive 链接可访问
178+
3. 确保 `app/libs/` 目录存在
179+
180+
### Q: 子模块未初始化
181+
**A:**
182+
```bash
183+
git submodule update --init --recursive
184+
```
185+
186+
---
187+
188+
## 📦 发布清单
189+
190+
发布新版本前检查:
191+
- [ ] 更新 `versionCode` (app/build.gradle.kts line 38)
192+
- [ ] 更新 `versionName` (app/build.gradle.kts line 39)
193+
- [ ] 更新 `README.md` 版本历程
194+
- [ ] 测试所有核心功能
195+
- [ ] 创建 tag 并推送
196+
- [ ] 验证 CI/CD 构建成功
197+
- [ ] 检查 GitHub Release 内容
198+
199+
---
200+
201+
## 🔗 相关链接
202+
203+
- [项目主页](https://github.com/AAswordman/Operit)
204+
- [用户指南](https://aaswordman.github.io/OperitWeb)
205+
- [开发文档](docs/CONTRIBUTING.md)
206+
- [依赖下载](https://drive.google.com/drive/folders/1g-Q_i7cf6Ua4KX9ZM6V282EEZvTVVfF7)

.github/workflows/debug-build.yml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
name: Build Debug APK
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- dev
8+
- me # 用于测试的分支
9+
pull_request:
10+
workflow_dispatch: # 允许手动触发
11+
12+
jobs:
13+
build-debug:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: write
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
with:
22+
submodules: recursive
23+
24+
- name: Set up JDK 17
25+
uses: actions/setup-java@v4
26+
with:
27+
java-version: '17'
28+
distribution: 'temurin'
29+
cache: gradle
30+
31+
- name: Create local.properties
32+
run: |
33+
echo "GITHUB_CLIENT_ID=${{ secrets.GITHUB_CLIENT_ID }}" >> local.properties
34+
echo "GITHUB_CLIENT_SECRET=${{ secrets.GITHUB_CLIENT_SECRET }}" >> local.properties
35+
36+
- name: Grant execute permission for gradlew
37+
run: chmod +x gradlew
38+
39+
- name: Download and Extract Sherpa NCNN Library
40+
run: |
41+
# Create target directory
42+
mkdir -p app/src/main/jniLibs/arm64-v8a
43+
44+
# Download the APK containing the library
45+
curl -L -o sherpa.apk https://github.com/k2-fsa/sherpa-ncnn/releases/download/v2.1.15/sherpa-ncnn-2.1.15-cpu-arm64-v8a-bilingual-en-zh.apk
46+
47+
# Extract all library files from the APK
48+
unzip -j sherpa.apk "lib/arm64-v8a/*.so" -d app/src/main/jniLibs/arm64-v8a/
49+
50+
# Create assets directory
51+
mkdir -p app/src/main/assets/models
52+
53+
# Extract model assets
54+
unzip -q sherpa.apk "assets/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/*" -d temp_assets
55+
mv temp_assets/assets/sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13 app/src/main/assets/models/
56+
rm -rf temp_assets
57+
58+
# Verify files exist
59+
ls -l app/src/main/jniLibs/arm64-v8a/
60+
ls -R app/src/main/assets/models/
61+
62+
- name: Configure Modules to Skip Stripping libsudo.so
63+
run: |
64+
# Configure terminal module
65+
if [ -f terminal/build.gradle.kts ]; then
66+
echo "" >> terminal/build.gradle.kts
67+
echo 'android { packaging { jniLibs { keepDebugSymbols.add("**/libsudo.so") } } }' >> terminal/build.gradle.kts
68+
echo "Added keepDebugSymbols for libsudo.so to terminal/build.gradle.kts"
69+
elif [ -f terminal/build.gradle ]; then
70+
echo "" >> terminal/build.gradle
71+
echo 'android { packagingOptions { doNotStrip "**/libsudo.so" } }' >> terminal/build.gradle
72+
echo "Added doNotStrip for libsudo.so to terminal/build.gradle"
73+
else
74+
echo "Terminal build file not found!"
75+
ls -R terminal
76+
exit 1
77+
fi
78+
79+
# Configure app module
80+
if [ -f app/build.gradle.kts ]; then
81+
sed -i '/packaging {/a\ jniLibs {\n keepDebugSymbols.add("**/libsudo.so")\n }' app/build.gradle.kts
82+
echo "Added keepDebugSymbols for libsudo.so to app/build.gradle.kts"
83+
else
84+
echo "App build file not found!"
85+
exit 1
86+
fi
87+
88+
- name: Fix Build Warnings
89+
run: |
90+
# Fix deprecated package attribute
91+
if [ -f terminal/src/main/AndroidManifest.xml ]; then
92+
sed -i 's/package="com.ai.assistance.operit.terminal"//' terminal/src/main/AndroidManifest.xml
93+
echo "Removed deprecated package attribute from terminal/src/main/AndroidManifest.xml"
94+
fi
95+
96+
# Suppress C++ warnings
97+
if [ -f mnn/build.gradle.kts ]; then
98+
sed -i 's/"-std=c++17", "-fno-emulated-tls"/"-std=c++17", "-fno-emulated-tls", "-w"/' mnn/build.gradle.kts
99+
echo "Injected -w flag into mnn/build.gradle.kts"
100+
fi
101+
102+
- name: Build Debug APK
103+
run: ./gradlew assembleDebug
104+
105+
- name: Upload Debug APK as Artifact
106+
uses: actions/upload-artifact@v4
107+
with:
108+
name: operit-debug-apk
109+
path: app/build/outputs/apk/debug/app-debug.apk
110+
retention-days: 30
111+
112+
- name: Upload Debug APK to Release (Optional)
113+
uses: softprops/action-gh-release@v1
114+
if: github.event_name == 'workflow_dispatch'
115+
with:
116+
tag_name: debug-${{ github.run_number }}
117+
name: Debug Build #${{ github.run_number }}
118+
files: app/build/outputs/apk/debug/app-debug.apk
119+
draft: true
120+
prerelease: true

0 commit comments

Comments
 (0)