lan a0ef7f430d Initial updates server repository commit.
Reinitialize repository history and exclude generated OTA artifact outputs.

Made-with: Cursor
2026-03-09 21:33:34 +08:00

Expo Updates Server (Go)

这个目录是 expo-updates-server 的 Go 版本实现,目标是:

  • 保持客户端接口兼容:GET /api/manifestGET /api/assets
  • 增加便于上传和 CI 的管理接口:/admin/publish/admin/rollback/admin/releases

运行

cd expo-updates-server-go
go run ./cmd/server

默认监听 :3001,可通过环境变量覆盖:

  • PORT:默认 3001
  • HOSTNAME:默认 http://localhost:3001,用于拼接 assets URL
  • UPDATES_ROOT:默认 updates
  • PRIVATE_KEY_PATH:可选;若客户端请求 expo-expect-signature,必须配置
  • ADMIN_TOKEN:管理接口 Bearer Token

示例(复用现有 expo-updates-server/updates

cd expo-updates-server-go
PORT=3001 \
HOSTNAME=http://localhost:3001 \
UPDATES_ROOT=../expo-updates-server/updates \
PRIVATE_KEY_PATH=../expo-updates-server/code-signing-keys/private-key.pem \
ADMIN_TOKEN=dev-token \
go run ./cmd/server

生产环境建议将 HOSTNAME 配置为:

https://updates.littlelan.cn

兼容接口

  • GET /api/manifest
    • 支持 expo-platformexpo-runtime-versionexpo-protocol-version
    • 支持 rollBackToEmbeddednoUpdateAvailable
    • 支持 expo-expect-signature
  • GET /api/assets?asset=...&runtimeVersion=...&platform=...

管理接口(上传/CI

1) 发布 zip

POST /admin/publish?runtimeVersion=<rv>&platform=<ios|android>

  • HeaderAuthorization: Bearer <ADMIN_TOKEN>
  • Bodyexpo export 产物 zipzip 根目录需包含 metadata.json
curl -X POST \
  "https://updates.littlelan.cn/admin/publish?runtimeVersion=2&platform=ios" \
  -H "Authorization: Bearer dev-token" \
  -H "Content-Type: application/zip" \
  --data-binary @dist.zip

2) 创建回滚标记

POST /admin/rollback

curl -X POST "https://updates.littlelan.cn/admin/rollback" \
  -H "Authorization: Bearer dev-token" \
  -H "Content-Type: application/json" \
  -d '{"runtimeVersion":"2","platform":"ios"}'

3) 查看发布列表

GET /admin/releases?runtimeVersion=2

curl "https://updates.littlelan.cn/admin/releases?runtimeVersion=2" \
  -H "Authorization: Bearer dev-token"

CI 示例思路

  1. 在客户端跑 npx expo export
  2. 打包 dist 为 zip
  3. 调用 /admin/publish

可直接参考根目录新增工作流:.github/workflows/go-updates-server-ci.yml

Docker 打包与运行

1) 构建镜像并导出 tar

expo-updates-server-go 目录执行:

./build-docker-tar.sh

可指定 tag

./build-docker-tar.sh 20260309-ota

执行后会生成:

  • 镜像:carrot-bbs-updates-server:<tag>
  • tarcarrot-bbs-updates-server-<tag>.tar

2) 运行容器(挂载更新目录和密钥)

docker run -d \
  --name carrot-bbs-updates-server \
  -p 3001:3001 \
  -e PORT=3001 \
  -e HOSTNAME=https://updates.littlelan.cn \
  -e UPDATES_ROOT=/data/updates \
  -e PRIVATE_KEY_PATH=/data/privatekey.pem \
  -e ADMIN_TOKEN=dev-token \
  -v /opt/carrot-bbs/updates:/data/updates \
  -v /opt/carrot-bbs/keys/privatekey.pem:/data/privatekey.pem:ro \
  carrot-bbs-updates-server:latest
Description
No description provided
Readme 38 KiB
Languages
Go 96%
Shell 2.6%
Dockerfile 1.4%