Files
UUVPN/.github/workflows/README.md
T

525 lines
14 KiB
Markdown

# GitHub Actions CI/CD 配置说明
本文档说明如何配置和使用 UUVPN 的 GitHub Actions 自动构建流程。
---
## 📋 目录
- [功能特性](#功能特性)
- [前置要求](#前置要求)
- [配置 Secrets](#配置-secrets)
- [使用方法](#使用方法)
- [构建产物](#构建产物)
- [自定义配置](#自定义配置)
- [常见问题](#常见问题)
---
## 功能特性
### ✅ 自动构建
- **Android APK**: 支持 Debug 和 Release 构建
- **iOS IPA**: 支持 Debug 和 Release 构建
- **多架构支持**: Android 支持 armeabi-v7a, arm64-v8a, x86, x86_64
### ✅ 自动发布
- **GitHub Releases**: 自动创建 Release 并上传构建产物
- **TestFlight**: 自动上传 iOS 版本到 TestFlight
- **Telegram 通知**: 构建完成后发送通知
### ✅ 触发条件
- 推送到 main/develop 分支
- 创建版本标签 (v*)
- Pull Request
- 手动触发
---
## 前置要求
### Android 构建
1. **JDK 11**: 已在 Actions 中自动配置
2. **Android SDK**: 已在 Actions 中自动配置
3. **Go 1.23**: 用于编译核心库
4. **签名密钥**: Release 构建需要签名密钥库
### iOS 构建
1. **Apple Developer 账号**: $99/年
2. **Xcode 15.0+**: 已在 Actions 中自动配置
3. **开发者证书**: .p12 格式
4. **Provisioning Profile**: .mobileprovision 文件
5. **App Store Connect API Key**: 用于上传到 TestFlight
---
## 配置 Secrets
在 GitHub 仓库中配置以下 Secrets:
### Android Secrets
| Secret 名称 | 描述 | 获取方式 |
|------------|------|---------|
| `ANDROID_KEYSTORE_BASE64` | 签名密钥库的 Base64 编码 | 见下方说明 |
| `ANDROID_KEYSTORE_PASSWORD` | 密钥库密码 | 创建密钥库时设置 |
| `ANDROID_KEY_ALIAS` | 密钥别名 | 创建密钥库时设置 |
| `ANDROID_KEY_PASSWORD` | 密钥密码 | 创建密钥库时设置 |
**生成 ANDROID_KEYSTORE_BASE64**:
```bash
# 在本地执行
keytool -genkey -v -keystore release.keystore -alias uuvpn -keyalg RSA -keysize 2048 -validity 10000
# 转换为 Base64
base64 -i release.keystore -o release.keystore.base64
# 或者使用 PowerShell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("release.keystore")) | Out-File release.keystore.base64
```
### iOS Secrets
| Secret 名称 | 描述 | 获取方式 |
|------------|------|---------|
| `IOS_CERTIFICATES_P12` | 开发者证书的 Base64 编码 | 见下方说明 |
| `IOS_CERTIFICATES_PASSWORD` | 证书密码 | 导出证书时设置 |
| `IOS_SIGNING_IDENTITY` | 签名身份 | 如: "Apple Distribution: Your Name (TEAM_ID)" |
| `IOS_PROVISIONING_PROFILE` | Provisioning Profile 的 Base64 编码 | 见下方说明 |
| `IOS_TEAM_ID` | Apple Team ID | 在 Apple Developer 账号中查看 |
**生成 IOS_CERTIFICATES_P12**:
1. 在 Keychain Access 中导出证书
2. 选择 "Apple Distribution" 证书
3. 右键 → 导出 → 选择 .p12 格式
4. 设置密码
5. 转换为 Base64:
```bash
base64 -i certificate.p12 -o certificate.p12.base64
# 或者使用 PowerShell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("certificate.p12")) | Out-File certificate.p12.base64
```
**生成 IOS_PROVISIONING_PROFILE**:
1. 在 Apple Developer 网站下载 Provisioning Profile
2. 转换为 Base64:
```bash
base64 -i uuvpn.mobileprovision -o uuvpn.mobileprovision.base64
# 或者使用 PowerShell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("uuvpn.mobileprovision")) | Out-File uuvpn.mobileprovision.base64
```
### App Store Connect Secrets
| Secret 名称 | 描述 | 获取方式 |
|------------|------|---------|
| `APP_STORE_CONNECT_ISSUER_ID` | App Store Connect API Issuer ID | 在 App Store Connect 中创建 API Key |
| `APP_STORE_CONNECT_API_KEY_ID` | App Store Connect API Key ID | 创建 API Key 时获得 |
| `APP_STORE_CONNECT_API_PRIVATE_KEY` | App Store Connect API 私钥 | 创建 API Key 时下载的 .p8 文件内容 |
**获取方式**:
1. 登录 [App Store Connect](https://appstoreconnect.apple.com/)
2. 进入 Users and Access → Keys
3. 点击 "Generate API Key"
4. 选择 "App Manager" 权限
5. 下载 .p8 文件并保存私钥内容
### 通知 Secrets (可选)
| Secret 名称 | 描述 | 获取方式 |
|------------|------|---------|
| `TELEGRAM_BOT_TOKEN` | Telegram Bot Token | 通过 @BotFather 创建 Bot |
| `TELEGRAM_CHAT_ID` | Telegram 群组/频道 ID | 邀请 Bot 到群组后获取 |
**获取方式**:
1. 在 Telegram 中找到 @BotFather
2. 发送 `/newbot` 创建新 Bot
3. 获取 Bot Token
4. 创建群组或频道,邀请 Bot
5. 获取 Chat ID: `https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates`
---
## 使用方法
### 方法一: 自动触发
#### 推送到分支
```bash
# 推送到 main 分支,触发构建
git push origin main
# 推送到 develop 分支,触发 Debug 构建
git push origin develop
```
#### 创建版本标签
```bash
# 创建 Alpha 版本
git tag v1.0.0-alpha
git push origin v1.0.0-alpha
# 创建 Beta 版本
git tag v1.0.0-beta
git push origin v1.0.0-beta
# 创建正式版本
git tag v1.0.0
git push origin v1.0.0
```
#### Pull Request
创建 Pull Request 到 main 分支会自动触发 Debug 构建。
### 方法二: 手动触发
1. 进入 GitHub 仓库
2. 点击 "Actions" 标签
3. 选择 "Build UUVPN" workflow
4. 点击 "Run workflow"
5. 选择构建选项:
- `build_android`: 是否构建 Android APK
- `build_ios`: 是否构建 iOS IPA
- `release_type`: 构建类型 (alpha/beta/release)
6. 点击 "Run workflow" 按钮
---
## 构建产物
### Android 构建产物
构建完成后,可以在以下位置找到 APK:
1. **Actions Artifacts**: 每个 workflow 运行都会保存 APK artifact
2. **GitHub Releases**: 创建标签后,APK 会自动上传到 Release
**APK 文件命名**:
- Debug: `app-meta-alpha-debug.apk`
- Release: `UUVPN-Android-v1.0.0.apk`
### iOS 构建产物
构建完成后,可以在以下位置找到 IPA:
1. **Actions Artifacts**: 每个 workflow 运行都会保存 IPA artifact
2. **GitHub Releases**: 创建标签后,IPA 会自动上传到 Release
3. **TestFlight**: Beta 和正式版本会自动上传到 TestFlight
**IPA 文件命名**:
- Release: `UUVPN-iOS-v1.0.0.ipa`
---
## 自定义配置
### 修改 Android 构建变体
编辑 `.github/workflows/build.yml` 中的构建命令:
```yaml
- name: Build Android APK
run: |
cd Android-kotlin-Code
# 修改为你需要的构建变体
./gradlew app:assembleMeta-BetaRelease --stacktrace
```
### 修改 iOS Scheme
编辑 `.github/workflows/build.yml` 中的 scheme:
```yaml
- name: Build iOS App
run: |
cd iOS-SwiftUI-Code
xcodebuild build \
-project uuvpn.xcodeproj \
-scheme SFT \ # 修改为你需要的 scheme
-sdk iphoneos \
...
```
### 添加构建缓存
在 workflow 中添加缓存以加速构建:
```yaml
- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Cache Swift packages
uses: actions/cache@v4
with:
path: |
~/Library/Caches/org.swift.swiftpm
.build
key: ${{ runner.os }}-swift-${{ hashFiles('**/Package.resolved') }}
restore-keys: |
${{ runner.os }}-swift-
```
### 添加自定义构建步骤
在 workflow 中添加自定义步骤:
```yaml
- name: Custom build step
run: |
# 你的自定义命令
echo "Running custom build step"
```
---
## 工作流程说明
### 完整构建流程
```
┌─────────────────┐
│ 触发构建 │
└────────┬────────┘
├─────────────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 构建 Android │ │ 构建 iOS │
│ APK │ │ IPA │
└────────┬────────┘ └────────┬────────┘
│ │
└──────────┬──────────┘
┌─────────────────────┐
│ 创建 GitHub Release │
│ (仅标签触发) │
└──────────┬──────────┘
├─────────────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 上传 APK 到 │ │ 上传 IPA 到 │
│ GitHub Release │ │ TestFlight │
└─────────────────┘ └─────────────────┘
┌─────────────────────┐
│ 发送通知 │
└─────────────────────┘
```
### 构建类型说明
| 触发条件 | Android | iOS | 发布 |
|---------|---------|-----|------|
| Push to develop | Debug APK | Debug App | 否 |
| Pull Request | Debug APK | Debug App | 否 |
| Push to main | Release APK | Release IPA | 否 |
| Tag v*-alpha | Release APK | Release IPA | GitHub Release (Pre-release) |
| Tag v*-beta | Release APK | Release IPA | GitHub Release + TestFlight |
| Tag v* | Release APK | Release IPA | GitHub Release + TestFlight |
---
## 常见问题
### Q1: Android 构建失败,提示找不到签名密钥?
**A**: 检查以下内容:
- 确认已配置 `ANDROID_KEYSTORE_BASE64` secret
- 确认 Base64 编码正确
- 确认密钥库密码、别名和密钥密码正确
### Q2: iOS 构建失败,提示签名错误?
**A**: 检查以下内容:
- 确认证书未过期
- 确认 Provisioning Profile 包含正确的 App ID
- 确认 Team ID 正确
- 确认证书和 Provisioning Profile 匹配
### Q3: iOS 构建时间过长?
**A**: iOS 构建通常需要 10-20 分钟,这是正常的。可以:
- 使用缓存加速构建
- 只在需要时构建 iOS 版本
- 使用手动触发选择性构建
### Q4: 如何跳过某个平台的构建?
**A**: 使用手动触发时,取消勾选对应平台的构建选项。
### Q5: 构建产物在哪里下载?
**A**:
1. 进入 Actions 页面
2. 点击具体的 workflow 运行记录
3. 在页面底部 "Artifacts" 区域下载
### Q6: 如何查看构建日志?
**A**:
1. 进入 Actions 页面
2. 点击具体的 workflow 运行记录
3. 点击左侧的 job 名称
4. 展开各个步骤查看详细日志
### Q7: TestFlight 上传失败?
**A**: 检查以下内容:
- 确认 App Store Connect API Key 配置正确
- 确认 API Key 有 App Manager 权限
- 确认 App ID 在 App Store Connect 中已创建
- 确认版本号未重复
### Q8: 如何修改构建触发条件?
**A**: 编辑 `.github/workflows/build.yml``on` 部分:
```yaml
on:
push:
branches:
- main
- develop
- feature/* # 添加更多分支
tags:
- 'v*'
pull_request:
branches:
- main
- develop
```
---
## 进阶配置
### 添加代码质量检查
在构建前添加代码检查:
```yaml
jobs:
lint:
name: Code Quality Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Android Lint
run: |
cd Android-kotlin-Code
./gradlew lint
- name: Swift Lint
run: |
brew install swiftlint
cd iOS-SwiftUI-Code
swiftlint
```
### 添加单元测试
```yaml
jobs:
test:
name: Run Tests
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Android Tests
run: |
cd Android-kotlin-Code
./gradlew test
- name: iOS Tests
run: |
cd iOS-SwiftUI-Code
xcodebuild test \
-project uuvpn.xcodeproj \
-scheme SFI \
-destination 'platform=iOS Simulator,name=iPhone 15'
```
### 添加多版本构建
```yaml
strategy:
matrix:
xcode-version: ['14.3', '15.0', '15.2']
include:
- xcode-version: '14.3'
ios-deployment-target: '14.0'
- xcode-version: '15.0'
ios-deployment-target: '15.0'
- xcode-version: '15.2'
ios-deployment-target: '16.0'
```
---
## 成本估算
### GitHub Actions 免费额度
- **总时长**: 每月 2000 分钟 (免费账户)
- **macOS runner**: 按 10 倍计算
- **Linux runner**: 按 1 倍计算
### 实际消耗估算
| 构建类型 | Android | iOS | 总计 |
|---------|---------|-----|------|
| Debug 构建 | ~5 分钟 | ~100 分钟 | ~105 分钟 |
| Release 构建 | ~10 分钟 | ~150 分钟 | ~160 分钟 |
| 完整流程 | ~15 分钟 | ~200 分钟 | ~215 分钟 |
### 建议
- 免费账户每月可进行约 **9-10 次完整构建**
- 建议只在必要时构建 iOS 版本
- 使用手动触发选择性构建
- 考虑升级 GitHub Pro 获得更多额度
---
## 总结
通过 GitHub Actions CI/CD 配置,你可以:
✅ 无需本地 Mac 设备即可构建 iOS 应用
✅ 自动化构建和发布流程
✅ 支持 Android 和 iOS 双平台
✅ 自动上传到 TestFlight 和 GitHub Releases
✅ 接收构建通知
配置好 Secrets 后,只需推送代码或创建标签,即可自动完成构建和发布!