Skip to content

Latest commit

 

History

920 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yohaku Remote Deploy

通过 GitHub Actions 构建 Yohaku Docker 镜像,推送到 GitHub Container Registry (GHCR),并调用 Dokploy API 触发部署。

路线(routes)

两套并行:

route 源分支 rolling tags immutable tag dokploy app secret
main main (Next.js, 未来合 remix 后变 RR7) latest, main, nextjs main-<sha> DOKPLOY_APP_ID_MAIN
remix refactor/remix (React Router 7) remix remix-<sha> DOKPLOY_APP_ID_REMIX

:latest 永远跟 main,合并完成自然指向 RR7;:nextjs 是 Next.js 阶段之别名,merge 之日删除 deploy-main.yml 中此 tag,最后一份 build 即自动锁定为 Next.js archive。

工作流

yohaku 仓 push (main / refactor/remix)
       ↓
yohaku 仓 notify-remote-deploy.yml 调 repository_dispatch
       ↓
yohaku-remote-deploy 编排仓 deploy-<route>.yml
       ↓
检查 build_hash.<route> 去重 → 构建 Dockerfile → 推 GHCR
       ↓
调 Dokploy API 触发 redeploy
       ↓
Dokploy 拉新 image,部署

文件

.github/workflows/
  deploy-main.yml      # main route
  deploy-remix.yml     # remix route
  ship.yml             # iOS:fingerprint 相同发 OTA,否则 TestFlight
  testflight.yml       # iOS TestFlight(也可被 ship.yml 调用)
build_hash.main        # main route 去重指针(CI 自动维护)
build_hash.remix       # remix route 去重指针(CI 自动维护)

Dokploy 配置

Registry credential

Dashboard → Settings → Registry → Add Registry

字段
Name ghcr
Registry URL ghcr.io
Username GitHub 用户名
Password GitHub PAT (read:packages)

Application(main)

  • buildType: dockerImage
  • dockerImage: ghcr.io/innei/yohaku:latest
  • registry: ghcr

Application(remix)

  • buildType: dockerImage(务必从 dockerfile 切到 dockerImage
  • sourceType: docker(务必从 github 切到 docker,避免 dokploy 端再 build)
  • dockerImage: ghcr.io/innei/yohaku:remix
  • registry: ghcr

autoDeploy 可关可不关。GitHub Actions 完成后会显式 curl application.deploy 触发 redeploy。

触发方式

来源 触发哪个 workflow
yohaku 仓 push main repository_dispatch trigger-maindeploy-main.yml
yohaku 仓 push refactor/remix repository_dispatch trigger-remixdeploy-remix.yml
yohaku 仓 push mobile 相关路径 repository_dispatch trigger-shipship.yml(OTA 或 TestFlight)
yohaku 仓手动强制 IPA repository_dispatch trigger-ship + force_testflight,或 trigger-testflighttestflight.yml
手动 workflow_dispatch(部署支持 force_build;Ship 支持 source_ref / notes / force_testflight

编排仓自身 push 不再触发任何 build(避免改 workflow 时误触发部署)。

GitHub Secrets(yohaku-remote-deploy 仓)

Secret 说明
GH_PAT 可访问 innei-dev/yohaku 私有仓的 PAT(repo scope)
DOKPLOY_URL Dokploy 实例地址(不带尾部斜杠)
DOKPLOY_API_TOKEN Dokploy API Key
DOKPLOY_APP_ID_MAIN main route 的 Dokploy Application ID
DOKPLOY_APP_ID_REMIX remix route 的 Dokploy Application ID
BASE_URL Docker build-arg,站点根 URL(无尾部斜杠)
TELEGRAM_BOT_TOKEN (可选)Telegram 通知用 bot token
AFTER_DEPLOY_SCRIPT (可选)部署后执行的 shell 脚本
IOS_DIST_CERT_P12 Apple Distribution .p12 的 base64
IOS_DIST_CERT_PASSWORD 导出 .p12 时的密码
IOS_APPSTORE_PROFILE Yohaku App Store .mobileprovision 的 base64
ASC_KEY_ID App Store Connect API Key ID
ASC_ISSUER_ID App Store Connect API Issuer ID
ASC_API_KEY_P8 API key 的 .p8 原文
OTA_SERVER Expo OTA Worker 根 URL(https://ota.innei.in
OTA_API_KEY 该 app 的 upload API key

TestFlight / OTA

不用 EAS。ship.yml 先算 @expo/fingerprint@0.20.2,和仓库变量 YOHAKU_IOS_FINGERPRINT 比较:

  • 相同 → Ubuntu 跑 easc update --channel productionInnei/expo-ota
  • 缺失 / 不同 / force_testflight → 现有 macos TestFlight;上传后等待 App Store Connect 确认目标构建达到 VALID / IN_BETA_TESTING,再写回该变量

runtimeVersion.policyfingerprint。旧 1.0.0 包只吃旧 runtime 的 OTA。

TestFlight build 使用仓库变量 YOHAKU_IOS_BUILD_CURSOR,格式为 <marketing-version>:<last-reserved-build>。同一版本按整数递增;Expo marketing version 变化时从 1 重新开始。号码在 archive 前预留,失败构建 也不会回收,避免重试复用 Apple 已接收的 build。

yohaku 仓 Actions → Trigger Remote Ship
       ↓
repository_dispatch  event_type=trigger-ship
       ↓
yohaku-remote-deploy  ship.yml
       ↓
fingerprint == baseline ? OTA : TestFlight

TestFlight 本身:macos-26expo prebuildios/ 不进源仓),再 xcodebuild archive + exportArchive。上传后最多等待 45 分钟;Apple 处理失败或超时均不会更新 OTA runtime 基线。

不跟 build_hash.* 去重。CURRENT_PROJECT_VERSION 使用预留的 build cursor。同一时间只跑一条 TestFlight。

标识

Bundle ID in.innei
Team KAMM5N88X3
Profile name Yohaku

源仓 innei-dev/yohaku.github/workflows/trigger-testflight.yml(显示名 Trigger Remote Ship)用现有 secrets.PATrepository_dispatch

触发

  • 源仓:Actions → Trigger Remote Shipref 留空则用当前 run 的 SHA。勾 force_testflight 则跳过 OTA。
  • 编排仓:Actions → Ship (OTA or TestFlight),或 TestFlight (iOS) 直接打 IPA。

yohaku 仓 notify 配置

innei-dev/yohaku 仓内 .github/workflows/notify-remote-deploy.yml,监听 push: branches: [main, refactor/remix],按分支名调对应 repository_dispatch event。需要在 yohaku 仓配置:

Secret 说明
YOHAKU_REMOTE_DEPLOY_PAT 可对 Innei/yohaku-remote-deploy 执行 repository_dispatch 的 PAT(repo scope)

强制重建

在编排仓的 Actions 页面手动跑 workflow,勾 force_build: true,忽略 build_hash.<route> 比较直接 rebuild。

故障排除

Build 阶段:镜像推送失败

  1. GITHUB_TOKEN 需要 packages: write(workflow 已声明)
  2. 仓库 Settings → Actions → General → Workflow permissions = Read and write
  3. 仓库 Settings → Actions → General → Allow GitHub Actions to create and approve pull requests(store job push hash 用)

Deploy 阶段:Dokploy 调用失败

  1. DOKPLOY_URL 不带尾部斜杠
  2. DOKPLOY_API_TOKEN 在 Dokploy Profile → Generate API Key
  3. DOKPLOY_APP_ID_* 取自 Application URL 末段

Dokploy 拉取 image 失败

  1. Settings → Registry 已配 ghcr 凭证,PAT 含 read:packages
  2. Application 配的 dockerImage 路径正确(注意 GHCR owner 大小写)
  3. GHCR package 已公开,或 dokploy 凭证有访问权

切到 RR7 (main) 后的清理

refactor/remix 合并进 main 后:

  1. deploy-remix.ymlbuild_hash.remix
  2. deploy-main.yml:nextjs tag(保留 :latest :main :main-<sha>
  3. Dokploy 删 remix application,main application dockerImage 不需要改
  4. yohaku 仓 notify-remote-deploy.yml 去掉 refactor/remix 分支

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Stars

16 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors