Files
codex-app-server/.github/workflows/release.yml
T
openqjandhost fc8e337d0f HA 阶段 1:worktree_host + 跨主机 /pr 队列化 (#50)
* 部署自动化:唯一发布链路 deploy.py + host_deploy.sh,sha/commit 双重验真,失败回滚

旧链路三次栽过的坑:通用 tar 路径导致旧包误部署、传输不验 sha、
主机脚本多份漂移、health 通过不等于新代码上线。本单把四点变硬门禁:
- 产物唯一命名 codex-app-server-<commit>.tar.gz + .sha256,远端唯一路径
- git archive 产物 + DEPLOYED_COMMIT 清单,默认拒绝脏工作区
- 传输链 scp -> scp_run -> chunk 分片,每路传完远端验 sha,不符删掉重来
- 主机侧唯一脚本:先验 sha/清单,staging 解包 + 编译检查,换目录上线,
  work/ 原样保留,health + 上线 commit 不符即回滚并退出非零
- deploy.py 成功后独立 ssh 再读一次 live 清单二次核对
- CI:host-verify 加 deploy/tests;release.yml 只在手动/tag + production
  environment 审批时部署,主干推送绝不自动部署生产
- deploy.sh 标记为旧链路弃用
- health 的 commit 字段已在父提交 HA 阶段 0 里随 server.py 落地,
  本分支整体包含它;commit 为空时只靠文件核对,门禁同样成立
测试:host 32、cloud 487(4 跳过)、deploy 9,全部通过;
host_deploy.sh 仿真覆盖成功/坏 sha/清单不符/health commit 不符回滚。
生产实机部署未做,等确认后再用新链路推。

* HA stage 1: worktree_host + queued cross-host PR jobs

---------

Co-authored-by: host <host@test.local>
2026-10-27 00:05:18 +08:00

96 lines
3.9 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: release
# 发布链路:主干推送绝不自动部署生产。
# 触发只有两种,两种都要经过 host-verify 同款测试:
# 1. 手动 workflow_dispatch(在 Actions 里点 Run,选 environment: production,
# GitHub 的 environment 审批人要点批准才会继续,见仓库 Settings > Environments)。
# 2. 打 tag v*(例如 v0.2.0),同样进 production environment 审批。
# 部署本身不由 Actions 直接拼 ssh 命令,而是复用 deploy/deploy.py:
# - 构建产物来自 git archive,含 DEPLOYED_COMMIT + sha256;
# - 传输、远端验 sha、主机 staging 换目录、失败回滚、RELEASE_OK 核对
# 全在 deploy.py / host_deploy.sh 里,Actions 只负责“何时触发 + 审批”。
# SSH 凭据只走 secrets,不写进日志:DEPLOY_HOST、DEPLOY_USER、
# DEPLOY_SSH_KEY(私钥内容,Actions 里写 ~/.ssh/id_ed25519,0600)。
# 没有配这些 secrets 时,build 作业仍产出可下载的发布包 artifact,
# deploy 作业会明确失败并提示“未配部署凭据,改走 VM 侧 deploy.py”,
# 绝不静默跳过部署又报成功。
on:
workflow_dispatch:
inputs:
ref:
description: "要部署的 ref(默认 main 的 HEAD)"
required: false
default: "main"
push:
tags:
- "v*"
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
outputs:
commit: ${{ steps.build.outputs.commit }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.ref }}
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: 测试(与 host-verify 同款,失败则不产发布包)
run: |
python3 -m unittest discover -s tests -v
python3 -m unittest discover -s cloud/tests -v
python3 -m unittest discover -s deploy/tests -v
- name: 构建发布包(git archive + DEPLOYED_COMMIT + sha256)
id: build
run: |
python3 deploy/deploy.py --build-only --skip-tests \
--ref "${{ inputs.ref || github.ref }}" \
--out-dir "$GITHUB_WORKSPACE/release-artifact"
echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
ls -lh release-artifact/
- name: 上传发布包 artifact
uses: actions/upload-artifact@v4
with:
name: codex-app-server-release
path: release-artifact/
retention-days: 30
deploy:
needs: build
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.ref }}
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: 下载发布包
uses: actions/download-artifact@v4
with:
name: codex-app-server-release
path: release-artifact
- name: 检查部署凭据是否齐全
run: |
if [ -z "${{ secrets.DEPLOY_HOST }}" ] || [ -z "${{ secrets.DEPLOY_SSH_KEY }}" ]; then
echo "未配 DEPLOY_HOST / DEPLOY_SSH_KEY,无法自动部署生产。" >&2
echo "发布包已在 artifact 里,改走 VM 侧:python3 deploy/deploy.py <host> --tarball <包> --skip-tests" >&2
exit 1
fi
- name: 写 SSH key(0600,不打印)
run: |
mkdir -p ~/.ssh
printf '%s\n' "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
- name: 部署(deploy.py:传输验 sha + 主机换目录 + 回滚 + 双重核对)
env:
SSH_PROXY_CMD: ""
run: |
TARBALL=$(ls release-artifact/*.tar.gz | head -n 1)
DEPLOY_USER="${{ secrets.DEPLOY_USER }}"
python3 deploy/deploy.py "${{ secrets.DEPLOY_HOST }}" \
"${DEPLOY_USER:-root}" \
--tarball "$TARBALL" --skip-tests