feat: 回忆录证据血缘与内部评测可追溯,顺带对齐本地评测台与 CI

数据库与模型:新增多版迁移(章节证据快照、对话血缘、记忆事实/时间线 lineage 等),把「成稿 ↔ 对话/记忆」的溯源信息落到表结构里。
业务链路:会话与 WS、回忆录/故事流水线、记忆写入与 enrichment 等跟着接上线索与快照;新增章节证据快照与评测侧 EvalTraceService 等模块,方便组评审用的证据包。
内部评测:自动化 run 与手工 memoir 评审共用可追溯证据;rubric/ judge 相关脚本与文档有配套调整。
app-eval-web:Memoir/实验详情里能展开看证据摘要与 evidence_trace(含对话轮次 id);Vite 代理与 development.sh 注入的 API 端口与当前默认内部评测端口一致,避免改端口后页面连错服务。
工程杂项:GitHub Actions / 仓库说明有更新;各适配器与支付/配额/plan 等多处为小改动或跟随主改动的收尾;新增/扩充了?
This commit is contained in:
Kevin
2026-04-08 15:37:09 +08:00
parent 6772e1269c
commit 309a051038
109 changed files with 4125 additions and 858 deletions

View File

@@ -1,325 +1,18 @@
# GitHub Actions CI/CD 工作流配置说明
# GitHub Actions 说明
## 工作流列表
## APIDocker Build and Deploy
| 工作流 | 说明 | 文档 |
|--------|------|------|
| Docker Build and Deploy | API 镜像构建与部署 | 见下文 |
| Android Release Build | Android APK 构建与发布 | 见下文 |
| App Expo Deploy | app-expo Web 构建与发布 | [docs/app-expo-deploy.md](../../docs/app-expo-deploy.md) |
- **工作流文件** [docker-build-deploy.yml](docker-build-deploy.yml)
- **测试 job**:在构建镜像前于 `api/` 下执行 `uv sync --dev``pytest`
- **Secrets**:预发 `STAGING_*`、生产 `PROD_*`、镜像 `ALIYUN_CR_*` — 详见 [SETUP.md](SETUP.md)。
- **分支 / Tag**`main` → 预发;语义化 tag `v*.*.*` → 生产;路径过滤为 `api/**` 与本 workflow。
---
头部注释与 `docker-build-deploy.yml` 内说明为最新权威描述。
## 概述
## Android Release
本工作流实现了自动化的 Docker 镜像构建和部署流程:
构建签名 APK见本文件历史版本中 Android 小节或仓库内 app 模块文档(若已迁移)。
1. **构建阶段**:当代码推送到指定分支时,自动构建 Docker 镜像
2. **推送阶段**将构建好的镜像推送到阿里云容器镜像服务ACR
3. **部署阶段**:通过 SSH 连接到远程服务器,拉取最新镜像并重建容器
## App Expo Deploy
## 工作流触发条件
- 推送到 `main``master``develop` 分支
- 仅当 `api/` 目录或 `.github/workflows/` 目录有变更时触发
- 支持手动触发workflow_dispatch
## 配置步骤
### 1. 配置 GitHub Secrets
在 GitHub 仓库设置中添加以下 Secrets
#### 必需配置
- **SSH_PRIVATE_KEY**: SSH 私钥,用于连接到远程服务器
```bash
# 生成 SSH 密钥对(如果还没有)
ssh-keygen -t ed25519 -C "github-actions"
# 将私钥添加到 GitHub Secrets
cat ~/.ssh/id_ed25519 # 复制内容到 SSH_PRIVATE_KEY
# 将公钥添加到远程服务器的 ~/.ssh/authorized_keys
cat ~/.ssh/id_ed25519.pub | ssh user@your-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
```
- **SSH_USER**: SSH 用户名(例如:`root`、`ubuntu`、`deploy`
- **SSH_HOST**: 远程服务器 IP 地址或域名(例如:`192.168.1.100`、`example.com`
#### 阿里云容器镜像服务配置(必需)
- **ALIYUN_CR_USERNAME**: 阿里云容器镜像服务用户名(例如:`zaikunxu`
- **ALIYUN_CR_PASSWORD**: 阿里云容器镜像服务密码
#### 可选配置
- **SSH_PORT**: SSH 端口(默认:`22`
- **DEPLOY_PATH**: 远程服务器上的部署目录(默认:`/opt/life-echo`
### 2. 容器镜像仓库配置
本工作流使用**阿里云容器镜像服务ACR**作为镜像仓库。
#### 镜像地址
- 镜像仓库地址:`crpi-u2903xccyzd6nqnc.cn-shanghai.personal.cr.aliyuncs.com`
- 命名空间:`huaga`
- 镜像名称:`lifecho-api`
- 完整镜像路径:`crpi-u2903xccyzd6nqnc.cn-shanghai.personal.cr.aliyuncs.com/huaga/lifecho-api:latest`
#### 配置说明
工作流已配置为使用阿里云容器镜像服务,无需修改工作流文件。只需在 GitHub Secrets 中配置:
- `ALIYUN_CR_USERNAME`: 阿里云容器镜像服务用户名
- `ALIYUN_CR_PASSWORD`: 阿里云容器镜像服务密码
#### 在远程服务器上配置 Docker 登录
确保远程服务器可以拉取私有镜像,需要在远程服务器上执行:
```bash
docker login crpi-u2903xccyzd6nqnc.cn-shanghai.personal.cr.aliyuncs.com \
--username=zaikunxu \
--password=57ucV,g4LF2cqm8
```
或者将登录信息添加到工作流的部署步骤中(已自动配置)。
### 3. 远程服务器准备
确保远程服务器已安装:
- Docker
- Docker Compose
```bash
# 安装 DockerUbuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Docker Compose V2命令为 docker compose带空格
# 多数 Docker 安装已包含插件;若提示找不到 compose
# sudo apt-get update && sudo apt-get install -y docker-compose-plugin
```
### 4. 首次部署准备
在远程服务器上创建部署目录:
```bash
mkdir -p /opt/life-echo/api
```
确保 SSH 用户可以访问该目录并执行 Docker 命令。
## 工作流执行流程
### 构建阶段build-and-push
1. 检出代码
2. 设置 Docker Buildx
3. 登录到容器镜像仓库
4. 提取元数据(标签、标签)
5. 构建并推送 Docker 镜像
### 部署阶段deploy
1. 设置 SSH 连接
2. 登录到容器镜像仓库(在远程服务器上)
3. 拉取最新镜像
4. 停止现有容器
5. 更新 docker-compose.yml 中的镜像标签
6. 启动新容器
7. 清理旧镜像
8. 验证部署状态
## 镜像标签规则
- `main`/`master` 分支 → `latest`
- 其他分支 → 使用分支名作为标签
- 同时会生成基于 commit SHA 的标签
## 故障排查
### 1. SSH 连接失败
- 检查 `SSH_PRIVATE_KEY` 是否正确配置
- 确认远程服务器的 SSH 服务正在运行
- 验证 SSH 公钥已添加到远程服务器的 `~/.ssh/authorized_keys`
### 2. Docker 登录失败
- 检查 `ALIYUN_CR_USERNAME` 和 `ALIYUN_CR_PASSWORD` 是否正确配置
- 确认阿里云容器镜像服务的账号密码是否正确
- 检查远程服务器是否可以访问阿里云容器镜像服务
### 3. 镜像拉取失败
- 确认远程服务器可以访问容器镜像仓库
- 检查镜像标签是否正确
- 验证网络连接
### 4. 容器启动失败
- 检查 docker-compose.yml 文件是否正确
- 查看容器日志:`docker compose logs`
- 确认环境变量配置正确
## 手动触发
可以通过 GitHub Actions 界面手动触发工作流:
1. 进入仓库的 Actions 标签页
2. 选择 "Docker Build and Deploy" 工作流
3. 点击 "Run workflow" 按钮
## 自定义配置
### 修改触发分支
编辑 `.github/workflows/docker-build-deploy.yml`
```yaml
on:
push:
branches:
- your-branch-name
```
### 修改镜像名称
编辑工作流文件中的 `IMAGE_NAME` 和 `REGISTRY_NAMESPACE` 环境变量:
```yaml
env:
IMAGE_NAME: your-image-name
REGISTRY_NAMESPACE: your-namespace
```
### 修改部署路径
在 GitHub Secrets 中设置 `DEPLOY_PATH`,或直接修改工作流文件中的默认值。
## 注意事项
1. **安全性**:确保 SSH 私钥和密码等敏感信息只存储在 GitHub Secrets 中,不要提交到代码仓库
2. **权限**:确保 SSH 用户在远程服务器上有执行 Docker 命令的权限
3. **备份**:部署前会自动备份 docker-compose.yml 文件(`.bak` 后缀)
4. **回滚**:如果部署失败,可以使用备份文件恢复
## 相关文件
- 工作流文件:`.github/workflows/docker-build-deploy.yml`
- Dockerfile`api/Dockerfile`
- Docker Compose`api/docker-compose.yml`
---
# Android Release 工作流
## 概述
自动构建生产环境签名 APK 并发布到 GitHub Releases
1. **构建阶段**:编译 Release APK使用生产签名配置
2. **发布阶段**:创建 GitHub Release将 APK 作为附件上传
## 工作流触发条件
- **Tag 推送**:推送 `v*` 格式的标签时自动触发(如 `v1.0.0`、`v1.2.3-beta`
- **手动触发**:通过 GitHub Actions 界面手动触发,可选指定版本号
## 配置步骤
### 1. 配置 GitHub Secrets
在 GitHub 仓库设置中添加以下 Secrets
| Secret | 说明 | 示例 |
|--------|------|------|
| `ANDROID_KEYSTORE_BASE64` | keystore 文件的 Base64 编码 | 见下方生成方法 |
| `ANDROID_KEY_ALIAS` | 密钥别名 | `suiyueshishu` |
| `ANDROID_KEY_PASSWORD` | 密钥密码 | |
| `ANDROID_STORE_PASSWORD` | keystore 密码 | |
#### 生成 ANDROID_KEYSTORE_BASE64
```bash
# 在本地项目 app-android 目录下执行
base64 -i release-keystore.jks | pbcopy # macOS结果已复制到剪贴板
# Linux
base64 -w 0 release-keystore.jks
```
将输出内容粘贴到 GitHub Secrets 的 `ANDROID_KEYSTORE_BASE64` 中。
### 2. 版本号管理
- **Tag 触发**:从 tag 名自动提取版本号(如 `v1.0.0` → `versionName = "1.0.0"`
- **手动触发**:使用输入的 `version_name`,或使用 `build.gradle.kts` 中的默认值
- **versionCode**:自动使用 `GITHUB_RUN_NUMBER` 递增
### 3. 发布流程
#### 方式一:通过 Tag 自动发布
```bash
# 打标签并推送
git tag v1.0.0
git push origin v1.0.0
# 或者一步完成
git tag v1.0.0 && git push origin v1.0.0
```
工作流将自动:
1. 构建签名 Release APK
2. 上传 APK 为 GitHub Artifact
3. 创建 GitHub Release附带 APK 和自动生成的更新日志)
#### 方式二:手动触发
1. 进入仓库的 Actions 标签页
2. 选择 "Android Release Build" 工作流
3. 点击 "Run workflow" 按钮
4. (可选)填写版本号
5. 点击 "Run workflow"
手动触发时仅构建 APK 并上传为 Artifact不会创建 GitHub Release。
## 工作流执行流程
1. 检出代码(完整历史)
2. 确定版本号Tag / 手动输入 / build.gradle.kts 默认值)
3. 设置 JDK 17 + Gradle 缓存
4. 解码签名 keystore + 生成 keystore.properties
5. 覆盖 build.gradle.kts 中的版本号
6. 执行 `./gradlew assembleRelease`
7. 上传 APK 为 Artifact保留 30 天)
8. Tag 触发时)生成 Release Notes 并创建 GitHub Release
## APK 命名规则
APK 文件命名格式:`岁月时书_v{版本号}_release.apk`
示例:`岁月时书_v1.0.0_release.apk`
## 故障排查
### 1. 签名失败
- 检查 `ANDROID_KEYSTORE_BASE64` 是否正确生成(不能有换行或空格)
- 确认 `ANDROID_KEY_ALIAS`、`ANDROID_KEY_PASSWORD`、`ANDROID_STORE_PASSWORD` 与 keystore 匹配
### 2. 构建失败
- 检查 Actions 日志中的 Gradle 错误输出
- 确认本地 `./gradlew assembleRelease` 可以成功
### 3. Release 创建失败
- 确认工作流有 `contents: write` 权限
- 检查 Tag 名称是否以 `v` 开头
见仓库 `docs/` 下相关说明(若存在)。

View File

@@ -1,83 +1,44 @@
# 快速配置指南
# Docker API 部署 — Secrets 快速清单
## GitHub Secrets 配置清单
与 [docker-build-deploy.yml](docker-build-deploy.yml) 保持一致。在 **Settings → Secrets and variables → Actions** 中配置(仓库级 Secrets
在 GitHub 仓库的 **Settings → Secrets and variables → Actions** 中添加以下 Secrets
## 必需
### 必需配置
| Secret | 说明 |
|--------|------|
| `STAGING_SSH_PRIVATE_KEY` | 预发机 SSH 私钥全文 |
| `STAGING_SSH_HOST` | 预发机主机名或 IP |
| `STAGING_SSH_USER` | SSH 用户名 |
| `STAGING_SSH_PORT` | SSH 端口(默认 `22` |
| `STAGING_DEPLOY_PATH` | 预发机上的部署目录 |
| `PROD_SSH_PRIVATE_KEY` | 生产机 SSH 私钥(可与预发不同) |
| `PROD_SSH_HOST` | 生产机主机 |
| `PROD_SSH_USER` | 生产 SSH 用户 |
| `PROD_SSH_PORT` | 生产 SSH 端口 |
| `PROD_DEPLOY_PATH` | 生产部署目录 |
| `ALIYUN_CR_USERNAME` | 阿里云 ACR 用户名 |
| `ALIYUN_CR_PASSWORD` | 阿里云 ACR 密码 |
1. **SSH_PRIVATE_KEY**
- 描述SSH 私钥,用于连接到远程服务器
- 生成方法:
```bash
ssh-keygen -t ed25519 -C "github-actions"
cat ~/.ssh/id_ed25519 # 复制全部内容
```
- 将公钥添加到远程服务器:
```bash
cat ~/.ssh/id_ed25519.pub | ssh user@your-server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
```
> **Tag 部署**:推送 `v*.*.*`(如 `v1.2.0`)时使用 `PROD_*`。**main 分支推送**使用 `STAGING_*`。
2. **SSH_USER**
- 描述SSH 用户名
- 示例:`root`、`ubuntu`、`deploy`
## 触发条件
3. **SSH_HOST**
- 描述:远程服务器 IP 或域名
- 示例:`192.168.1.100`、`example.com`
- `push``main`:改动了 `api/**``.github/workflows/**` 时,先跑 **API tests**`uv sync --dev` + `pytest`),再构建镜像并部署预发。
- `push` tag `v*.*.*`:同上路径过滤;部署生产。
- **workflow_dispatch**:可选手动指定 ref。
4. **ALIYUN_CR_USERNAME**
- 描述:阿里云容器镜像服务用户名
- 值:`zaikunxu`
仓库内需存在 **`api/.env.staging`** / **`api/.env.production`**(供部署 job 校验与上传);勿将真实密钥提交到公开分支。
5. **ALIYUN_CR_PASSWORD**
- 描述:阿里云容器镜像服务密码
- 值:`57ucV,g4LF2cqm8`
## 本地验证 SSH
### 可选配置
6. **SSH_PORT**
- 描述SSH 端口默认22
- 示例:`22`、`2222`
7. **DEPLOY_PATH**
- 描述:远程服务器部署目录(默认:/opt/life-echo
- 示例:`/opt/life-echo`、`/home/deploy/life-echo`
## 镜像信息
- **镜像仓库地址**`crpi-u2903xccyzd6nqnc.cn-shanghai.personal.cr.aliyuncs.com`
- **命名空间**`huaga`
- **镜像名称**`lifecho-api`
- **完整镜像路径**`crpi-u2903xccyzd6nqnc.cn-shanghai.personal.cr.aliyuncs.com/huaga/lifecho-api:latest`
## 验证配置
配置完成后,推送代码到 `main`、`master` 或 `develop` 分支,工作流会自动触发。
或者手动触发:
1. 进入仓库的 **Actions** 标签页
2. 选择 **Docker Build and Deploy** 工作流
3. 点击 **Run workflow** 按钮
## 常见问题
### 1. 如何查看工作流执行日志?
- 进入 **Actions** 标签页,点击对应的运行记录查看详细日志
### 2. 如何测试 SSH 连接?
```bash
ssh -i ~/.ssh/id_ed25519 user@your-server
ssh -i ~/.ssh/your_key -p 22 user@your-host
```
### 3. 如何测试 Docker 登录
## 本地验证 registry 登录
```bash
docker login crpi-u2903xccyzd6nqnc.cn-shanghai.personal.cr.aliyuncs.com \
--username=zaikunxu \
--password=57ucV,g4LF2cqm8
docker login <registry> --username=<ACR_USERNAME> --password-stdin
```
### 4. 部署失败怎么办?
- 检查 GitHub Actions 日志中的错误信息
- 确认远程服务器可以访问阿里云容器镜像服务
- 验证 SSH 连接和 Docker 权限
(密码从控制台或密钥管理读取,勿写入文档。)

View File

@@ -46,8 +46,28 @@ env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
test:
name: API tests
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v5
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "0.7.3"
- name: Sync deps and run pytest
working-directory: api
run: |
uv sync --dev
uv run pytest --tb=short -q
build-and-push:
name: Build and Push Docker Image
needs: test
runs-on: ubuntu-latest
permissions:
contents: read