docs(slark-cicd): document governed staging release (REQ-20261019-0001)
This commit is contained in:
@@ -5,8 +5,9 @@ description: Slark 仓库 staging、生产和 Desktop 安装包的端到端 CI/C
|
|||||||
|
|
||||||
# Slark CI/CD runbook
|
# Slark CI/CD runbook
|
||||||
|
|
||||||
驱动 Slark 从改代码到上线的端到端流程。权威流程与完整细节见仓库文档
|
驱动 Slark 从改代码到上线的端到端流程。环境身份与发布门禁见仓库文档
|
||||||
`docs/cicd-staging-production.md`(本技能命令与之一致);本文件是可直接照做的分阶段清单。
|
`docs/cicd-staging-production.md`;当前 governed staging 候选入口以仓库脚本契约和历史成功回执为准。
|
||||||
|
该文档中直接运行 `deploy-staging.sh` 的示例尚未列出当前脚本要求的不可变候选材料。
|
||||||
|
|
||||||
仓库:`qiudl/qiu-slark`(本机克隆通常在 `/Users/donglinlai/coding/slark`)。所有命令在**仓库根**执行。
|
仓库:`qiudl/qiu-slark`(本机克隆通常在 `/Users/donglinlai/coding/slark`)。所有命令在**仓库根**执行。
|
||||||
`ai-proj` 相关命令加 `GODEBUG=netdns=go` 前缀。
|
`ai-proj` 相关命令加 `GODEBUG=netdns=go` 前缀。
|
||||||
@@ -21,8 +22,8 @@ description: Slark 仓库 staging、生产和 Desktop 安装包的端到端 CI/C
|
|||||||
**每次都要人审**;命中审批闸就**等人批**,绝不绕过、绝不把这些 key 加进 auto-approve 白名单。
|
**每次都要人审**;命中审批闸就**等人批**,绝不绕过、绝不把这些 key 加进 auto-approve 白名单。
|
||||||
- staging 与生产硬隔离:staging 脚本带生产 IP 拒运行护栏、不 push origin、不反向 rsync。
|
- staging 与生产硬隔离:staging 脚本带生产 IP 拒运行护栏、不 push origin、不反向 rsync。
|
||||||
- 当前 Slark staging 权威目标是 AWS `ap-southeast-2` 实例 `i-013e5ca3fdfddc13e`
|
- 当前 Slark staging 权威目标是 AWS `ap-southeast-2` 实例 `i-013e5ca3fdfddc13e`
|
||||||
(Name=`slark-staging`,2026-08-18 核验公网 IP `15.135.112.181`)。公网 IP 自动分配,发布前必须按
|
(文档记录 Name=`slark-staging`;2026-10-23 只读核验公网 IP `15.135.112.181`)。公网 IP 自动分配,发布前必须按
|
||||||
实例 ID 重查并确认 Name/状态;不得凭历史 IP 判断目标。
|
实例 ID 从 AWS 控制面重查并确认 Name/状态/IP;不得凭历史 IP 或 SSH 可达性判断发布目标。
|
||||||
- `82.157.141.202` 是 ai-proj 预生产宿主机。其 `/opt/slark-staging` cohost 是隔离的 Slark 兼容验收栈,
|
- `82.157.141.202` 是 ai-proj 预生产宿主机。其 `/opt/slark-staging` cohost 是隔离的 Slark 兼容验收栈,
|
||||||
但不是 Slark 独立预生产;只有任务明确指定 cohost 时才能使用,不得作为普通 Slark staging 的默认目标。
|
但不是 Slark 独立预生产;只有任务明确指定 cohost 时才能使用,不得作为普通 Slark staging 的默认目标。
|
||||||
- staging 发布若影响 `packages/daemon`、`packages/runtime`、Server/daemon 公共协议或 Desktop 公共运行链,
|
- staging 发布若影响 `packages/daemon`、`packages/runtime`、Server/daemon 公共协议或 Desktop 公共运行链,
|
||||||
@@ -75,7 +76,8 @@ git branch -D <feature-branch> # 删本地(先切走)
|
|||||||
### 3.1 当前权威路径:Slark 独立 staging
|
### 3.1 当前权威路径:Slark 独立 staging
|
||||||
|
|
||||||
稳定目标是 AWS `ap-southeast-2` 实例 `i-013e5ca3fdfddc13e`(Name=`slark-staging`)。它使用自动分配
|
稳定目标是 AWS `ap-southeast-2` 实例 `i-013e5ca3fdfddc13e`(Name=`slark-staging`)。它使用自动分配
|
||||||
公网 IP,因此每次部署前先查询当前 IP;2026-08-18 核验值为 `15.135.112.181`:
|
公网 IP,因此每次部署前先查询当前 IP。`15.135.112.181` 是 2026-10-23 的只读核验值,
|
||||||
|
不是可直接用于将来发布的固定地址:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
aws ec2 describe-instances --region ap-southeast-2 \
|
aws ec2 describe-instances --region ap-southeast-2 \
|
||||||
@@ -83,20 +85,81 @@ aws ec2 describe-instances --region ap-southeast-2 \
|
|||||||
--query 'Reservations[0].Instances[0].{Name:Tags[?Key==`Name`]|[0].Value,State:State.Name,PublicIp:PublicIpAddress}' \
|
--query 'Reservations[0].Instances[0].{Name:Tags[?Key==`Name`]|[0].Value,State:State.Name,PublicIp:PublicIpAddress}' \
|
||||||
--output table
|
--output table
|
||||||
|
|
||||||
|
# 只使用上一步 AWS 返回且已核对 Name=slark-staging、State=running 的公网 IP。
|
||||||
|
export STAGING_IP='<verified-public-ip>'
|
||||||
export STAGING_SSH_KEY=~/.ssh/cloud-server-syd.pem
|
export STAGING_SSH_KEY=~/.ssh/cloud-server-syd.pem
|
||||||
export STAGING_REMOTE=ubuntu@15.135.112.181
|
export STAGING_REMOTE="ubuntu@$STAGING_IP"
|
||||||
export STAGING_REMOTE_IP=15.135.112.181
|
export STAGING_REMOTE_IP="$STAGING_IP"
|
||||||
export STAGING_BASE=http://15.135.112.181
|
export STAGING_BASE="http://$STAGING_IP"
|
||||||
|
# 使用 Slark 应用内的 project ID,不是 ai-proj 的数字项目/需求/任务 ID。
|
||||||
|
export SLARK_RELEASE_PROJECT_ID='<verified-slark-app-project-id>'
|
||||||
|
export SLARK_RELEASE_TASK_ID='REQ-...'
|
||||||
|
export SLARK_RELEASE_ID='release-staging-<40-sha>-<unique-attempt>'
|
||||||
|
# 普通发布还需从既有受信 provider 提供 mirror token;不要打印或写进日志。
|
||||||
|
|
||||||
scripts/deploy-staging.sh --migrate-dry-run
|
# 先确认候选 SHA 在 canonical GitHub 上可获取,且包含当前 main 的全部提交。
|
||||||
scripts/deploy-staging.sh
|
bash scripts/release-staging-governed.sh '<40-sha>'
|
||||||
STAGING_TOKEN=$(cat /tmp/.staging_token) scripts/staging-seed.sh
|
|
||||||
scripts/staging-verify-isolation.sh
|
scripts/staging-verify-isolation.sh
|
||||||
|
# 使用上一步发布输出的同一 release receipt;观察窗口未结束时保留原 receipt 重试。
|
||||||
|
scripts/complete-staging-verification.sh '<release-receipt-file>'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
这是历史 Slark 发布实际采用的 governed 入口:控制器从 canonical GitHub
|
||||||
|
获取不可变候选、持有本地锁,内层 `deploy-staging.sh` 执行远端构建、数据库迁移、
|
||||||
|
切换和健康检查。需要先单独演练迁移时,按仓库发布文档生成同一精确 SHA 的
|
||||||
|
`staging-candidate` manifest/archive/source,再向 `deploy-staging.sh --migrate-dry-run`
|
||||||
|
传入 `STAGING_CANDIDATE_MANIFEST`、`STAGING_CANDIDATE_ARCHIVE` 和
|
||||||
|
`STAGING_SOURCE_DIR`;当前 `deploy-staging.sh` 不接受缺少这些候选材料的直接调用。
|
||||||
|
这条演练在隔离数据库副本执行 pending up,不重启 Server;正式 governed 发布则在
|
||||||
|
live staging 数据库执行 migrate up。历史 2026-10-22 成功回执见
|
||||||
|
`acceptance/REQ-20261010-0007-rejection-execution-20261022/staging-deploy-r2.log`
|
||||||
|
与 `staging-verify-r2.log`。历史脚本里为特定 DSH UI 发布加入的配对、手动切换及回退步骤
|
||||||
|
不属于普通 Slark Server/daemon 发布命令,不能直接照搬。
|
||||||
|
|
||||||
不得把查询到的 Name 非 `slark-staging` 的机器当作目标。四件套细节与环境隔离约束见
|
不得把查询到的 Name 非 `slark-staging` 的机器当作目标。四件套细节与环境隔离约束见
|
||||||
`docs/req-20260811-0059-staging-environment-design.md`。
|
`docs/req-20260811-0059-staging-environment-design.md`。
|
||||||
|
|
||||||
|
**AWS 凭证不可用时的只读排查(2026-10-23 记录):**先查 Slark 自己的历史发布记录,
|
||||||
|
例如 `acceptance/REQ-20260930-0015/release-staging-main-history-window.sh`;其中记录的
|
||||||
|
staging IP 是 `15.135.112.181`,Slark 应用 release project ID 是
|
||||||
|
`tpqvorREPTj2kx9poKJWH`。这些值只是定位线索,使用前须重新核对。可用已有
|
||||||
|
`cloud-server-syd.pem`、`StrictHostKeyChecking=yes` 只读 SSH 到历史 IP,并核对远端
|
||||||
|
`/sys/devices/virtual/dmi/id/board_asset_tag`、IMDSv2 `instance-id` 与
|
||||||
|
`public-ipv4`;2026-10-23 三项分别核对为 `i-013e5ca3fdfddc13e`、
|
||||||
|
`i-013e5ca3fdfddc13e`、`15.135.112.181`,当时 `slark-server` 和
|
||||||
|
`slark-daemon-staging` 均在运行。不要输出 IMDS token 或应用凭证。
|
||||||
|
|
||||||
|
只读身份核验示例(历史 IP 仅用于定位;任何一项不匹配就停止):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh -i ~/.ssh/cloud-server-syd.pem -o BatchMode=yes \
|
||||||
|
-o StrictHostKeyChecking=yes -o ConnectTimeout=5 \
|
||||||
|
ubuntu@15.135.112.181 'bash -s' <<'STAGING_IDENTITY'
|
||||||
|
set -euo pipefail
|
||||||
|
tag="$(cat /sys/devices/virtual/dmi/id/board_asset_tag)"
|
||||||
|
token="$(curl -fsS --noproxy '*' --max-time 3 -X PUT \
|
||||||
|
-H 'X-aws-ec2-metadata-token-ttl-seconds: 60' \
|
||||||
|
http://169.254.169.254/latest/api/token)"
|
||||||
|
id="$(curl -fsS --noproxy '*' --max-time 3 \
|
||||||
|
-H "X-aws-ec2-metadata-token: $token" \
|
||||||
|
http://169.254.169.254/latest/meta-data/instance-id)"
|
||||||
|
ip="$(curl -fsS --noproxy '*' --max-time 3 \
|
||||||
|
-H "X-aws-ec2-metadata-token: $token" \
|
||||||
|
http://169.254.169.254/latest/meta-data/public-ipv4)"
|
||||||
|
test "$tag" = i-013e5ca3fdfddc13e
|
||||||
|
test "$id" = "$tag"
|
||||||
|
test "$ip" = 15.135.112.181
|
||||||
|
printf 'instance=%s public_ip=%s\n' "$id" "$ip"
|
||||||
|
STAGING_IDENTITY
|
||||||
|
```
|
||||||
|
|
||||||
|
这条 SSH/DMI/IMDS 路径只证明所连主机的实例身份,**不提供 AWS Name 标签的当次证明,
|
||||||
|
不能代替上面的发布前控制面核验**。`docs/runbooks/REQ-20260922-0005-staging-watchdog-emergency-recovery.md`
|
||||||
|
中的替代路径仅授权给那次特定事故,不能移用于普通 staging 发布。不要借用其他项目
|
||||||
|
的 AWS profile;若缺少 Slark AWS 控制面凭证,停在只读排查并记录缺口。2026-10-23
|
||||||
|
实例自带角色 `dsh-identity-staging-ec2` 调用 `DescribeInstances` 返回
|
||||||
|
`UnauthorizedOperation`,不能靠这个角色补齐 Name 核验。
|
||||||
|
|
||||||
### 3.2 非权威路径:ai-proj cohost(仅明确指定时)
|
### 3.2 非权威路径:ai-proj cohost(仅明确指定时)
|
||||||
|
|
||||||
ai-proj cohost 位于 `ubuntu@82.157.141.202:/opt/slark-staging`。全程使用隔离数据、数据库、密钥和状态目录,
|
ai-proj cohost 位于 `ubuntu@82.157.141.202:/opt/slark-staging`。全程使用隔离数据、数据库、密钥和状态目录,
|
||||||
|
|||||||
Reference in New Issue
Block a user