Files
jiu/.gitea/workflows/deploy-client.yml
T
wangjia 848a9ee2c6
Deploy Client / build-windows (push) Successful in 3m58s
Deploy Client / build-client-web (push) Successful in 6m17s
Deploy Client / build-macos (push) Successful in 13m39s
Deploy Client / build-android (push) Successful in 7m17s
Deploy Client / build-ios (push) Successful in 6m42s
Deploy Client / release-deploy-client (push) Successful in 11m50s
ci(deploy-client): iOS 上传加超时看门狗 + iOS 失败不阻断发版
1.1.13 发版事故复盘:build-ios 的 altool 上传静默卡死数分钟无输出,超
runner 僵尸超时被 SIGKILL 判失败(软失败 else 分支没机会跑);且 build-ios
被 release-deploy 硬 needs → 连带 web/mac/win/android 整体没部署。

- compile-ios.sh: altool 上传套后台看门狗(本机无 timeout/coreutils),超
  420s 先 TERM 再 KILL,保证永远在僵尸窗口内干净收尾,失败只告警不阻断。
- deploy-client.yml: build-ios 加 continue-on-error;release-deploy 改
  if: always() 只校验 4 个真实平台成功即部署,iOS 真正不阻塞。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bupi8Kdqkfx2N5acFsHTx5
2026-08-27 22:41:28 +08:00

234 lines
8.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Deploy Client
on:
push:
tags:
- 'client-v[0-9]*.[0-9]*.[0-9]*'
workflow_dispatch:
inputs:
windows_source:
description: 'Windows 构建来源:home=家里 runner(默认) / github=从 NAS 拉 GitHub 云构建'
required: false
default: home
type: choice
options: [home, github]
concurrency:
group: deploy-client
cancel-in-progress: false
jobs:
build-client-web:
runs-on: mac
env:
GOPROXY: https://goproxy.cn,direct
PUB_HOSTED_URL: https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
run: sh scripts/ci/provision-mac.sh
- name: Compile (Flutter Web)
run: sh scripts/ci/compile-client-web.sh "${{ gitea.ref_name }}"
- name: Upload web artifacts
uses: actions/upload-artifact@v3
with:
name: client-web
path: dist/
build-macos:
needs: build-client-web
runs-on: mac
env:
PUB_HOSTED_URL: https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
run: sh scripts/ci/provision-mac.sh
- name: Compile (Flutter macOS)
env:
MACOS_DEVELOPER_ID_CERT_P12_BASE64: ${{ secrets.MACOS_DEVELOPER_ID_CERT_P12_BASE64 }}
MACOS_DEVELOPER_ID_CERT_PASSWORD: ${{ secrets.MACOS_DEVELOPER_ID_CERT_PASSWORD }}
APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }}
APPSTORE_API_ISSUER_ID: ${{ secrets.APPSTORE_API_ISSUER_ID }}
APPSTORE_API_KEY_P8_BASE64: ${{ secrets.APPSTORE_API_KEY_P8_BASE64 }}
run: sh scripts/ci/compile-macos.sh "${{ gitea.ref_name }}"
- name: Upload macos artifacts
uses: actions/upload-artifact@v3
with:
name: macos
path: dist/
build-android:
needs: build-macos
runs-on: mac
env:
PUB_HOSTED_URL: https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
run: sh scripts/ci/provision-mac.sh
- name: Compile (Flutter Android APK)
env:
ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
run: sh scripts/ci/compile-android.sh "${{ gitea.ref_name }}"
- name: Upload android artifacts
uses: actions/upload-artifact@v3
with:
name: android
path: dist/
build-ios:
needs: build-android
runs-on: mac
# iOS TestFlight 上传易抖/易卡,按 CLAUDE.md「iOS 不阻塞发版」:本 job 失败
# 不拖垮整个 run,更不阻断下面的 release-deploy(它已改为只校验 4 个真实平台)。
continue-on-error: true
env:
PUB_HOSTED_URL: https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
steps:
- uses: actions/checkout@v4
- name: Provision (idempotent — auto-runs if host not initialized)
run: sh scripts/ci/provision-mac.sh
- name: Compile & upload to TestFlight (Flutter iOS)
env:
IOS_DIST_CERT_P12_BASE64: ${{ secrets.IOS_DIST_CERT_P12_BASE64 }}
IOS_DIST_CERT_PASSWORD: ${{ secrets.IOS_DIST_CERT_PASSWORD }}
IOS_PROVISIONING_PROFILE_BASE64: ${{ secrets.IOS_PROVISIONING_PROFILE_BASE64 }}
IOS_TEAM_ID: ${{ secrets.IOS_TEAM_ID }}
APPSTORE_API_KEY_ID: ${{ secrets.APPSTORE_API_KEY_ID }}
APPSTORE_API_ISSUER_ID: ${{ secrets.APPSTORE_API_ISSUER_ID }}
APPSTORE_API_KEY_P8_BASE64: ${{ secrets.APPSTORE_API_KEY_P8_BASE64 }}
run: sh scripts/ci/compile-ios.sh "${{ gitea.ref_name }}"
# Windows 单一 job(只显示一个节点)。按 windows_source 决定来源:
# home(默认) → 在家里 Windows runner 现编(provision + compile
# github → 在 mac 上从 GitHub Release 拉云构建的安装器(免 frps;家里 Windows 关机时用)
# 来源判定:运行参数 windows_source 优先,其次仓库变量 WINDOWS_SOURCE,默认 home。
build-windows:
runs-on: ${{ (github.event.inputs.windows_source || vars.WINDOWS_SOURCE || 'home') == 'github' && 'mac' || 'windows' }}
env:
GOPROXY: https://goproxy.cn,direct
PUB_HOSTED_URL: https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
steps:
- uses: actions/checkout@v4
# —— home 模式:家里 Windows runner 现编 ——
- name: Provision (home windows, idempotent)
if: ${{ (github.event.inputs.windows_source || vars.WINDOWS_SOURCE || 'home') != 'github' }}
shell: bash
run: sh scripts/ci/provision-windows.sh
- name: Compile Flutter Windows (home)
if: ${{ (github.event.inputs.windows_source || vars.WINDOWS_SOURCE || 'home') != 'github' }}
shell: bash
run: sh scripts/ci/compile-windows.sh "${{ gitea.ref_name }}"
# —— github 模式:mac 上从 GitHub Release 拉(免 frps)——
- name: Fetch installer from GitHub (免 frps)
if: ${{ (github.event.inputs.windows_source || vars.WINDOWS_SOURCE || 'home') == 'github' }}
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
GH_REPO: bj-wangjia/jiu
run: sh scripts/ci/fetch-windows-staged.sh "${{ gitea.ref_name }}"
- name: Upload windows artifacts
uses: actions/upload-artifact@v3
with:
name: windows
path: dist/
release-deploy-client:
needs: [build-client-web, build-macos, build-android, build-ios, build-windows]
# iOS(build-ios)故意可失败:只要 4 个真实平台成功就照常发布部署。
# always() 保证 build-ios 失败时本 job 不被跳过;再逐个校验其余平台必须成功。
if: >-
${{ always()
&& needs.build-client-web.result == 'success'
&& needs.build-macos.result == 'success'
&& needs.build-android.result == 'success'
&& needs.build-windows.result == 'success' }}
runs-on: mac
env:
GOPROXY: https://goproxy.cn,direct
PUB_HOSTED_URL: https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL: https://storage.flutter-io.cn
steps:
- uses: actions/checkout@v4
- name: Download web artifacts
uses: actions/download-artifact@v3
with:
name: client-web
path: dist/
- name: Download macos artifacts
uses: actions/download-artifact@v3
with:
name: macos
path: dist/
- name: Download android artifacts
uses: actions/download-artifact@v3
with:
name: android
path: dist/
- name: Download windows artifacts
uses: actions/download-artifact@v3
with:
name: windows
path: dist/
- name: Test (flutter analyze)
run: sh scripts/ci/test.sh client
- name: Release
env:
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
FORGEJO_URL: ${{ secrets.FORGEJO_URL }}
GITEA_REPOSITORY: ${{ gitea.repository }}
run: sh scripts/ci/release-client.sh "${{ gitea.ref_name }}"
# 2026-07-03 割接后阿里机即唯一发布目标(EC2 轨移除;EC2 仅保留
# jiu.51yanmei.com 反代桥接到 ali,见 baize 台账)。
- name: Deploy → Ali
env:
FORGEJO_TOKEN: ${{ secrets.FORGEJO_TOKEN }}
FORGEJO_URL: ${{ secrets.FORGEJO_URL }}
GITEA_REPOSITORY: ${{ gitea.repository }}
DEPLOY_SSH_KEY: ${{ secrets.ALI_SSH_KEY }}
DEPLOY_HOST: ${{ secrets.ALI_HOST }}
DEPLOY_USER: ${{ secrets.ALI_USER }}
run: sh scripts/ci/deploy-client.sh "${{ gitea.ref_name }}"
- name: Notify
if: always()
env:
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
run: sh scripts/ci/notify.sh "${{ gitea.ref_name }}" "${{ job.status }}"