diff --git a/skills-dev/slark-cicd-plugin/skills/SKILL.md b/skills-dev/slark-cicd-plugin/skills/SKILL.md index d65d536..571fa94 100644 --- a/skills-dev/slark-cicd-plugin/skills/SKILL.md +++ b/skills-dev/slark-cicd-plugin/skills/SKILL.md @@ -5,8 +5,9 @@ description: Slark 仓库 staging、生产和 Desktop 安装包的端到端 CI/C # Slark CI/CD runbook -驱动 Slark 从改代码到上线的端到端流程。权威流程与完整细节见仓库文档 -`docs/cicd-staging-production.md`(本技能命令与之一致);本文件是可直接照做的分阶段清单。 +驱动 Slark 从改代码到上线的端到端流程。环境身份与发布门禁见仓库文档 +`docs/cicd-staging-production.md`;当前 governed staging 候选入口以仓库脚本契约和历史成功回执为准。 +该文档中直接运行 `deploy-staging.sh` 的示例尚未列出当前脚本要求的不可变候选材料。 仓库:`qiudl/qiu-slark`(本机克隆通常在 `/Users/donglinlai/coding/slark`)。所有命令在**仓库根**执行。 `ai-proj` 相关命令加 `GODEBUG=netdns=go` 前缀。 @@ -21,8 +22,8 @@ description: Slark 仓库 staging、生产和 Desktop 安装包的端到端 CI/C **每次都要人审**;命中审批闸就**等人批**,绝不绕过、绝不把这些 key 加进 auto-approve 白名单。 - staging 与生产硬隔离:staging 脚本带生产 IP 拒运行护栏、不 push origin、不反向 rsync。 - 当前 Slark staging 权威目标是 AWS `ap-southeast-2` 实例 `i-013e5ca3fdfddc13e` - (Name=`slark-staging`,2026-08-18 核验公网 IP `15.135.112.181`)。公网 IP 自动分配,发布前必须按 - 实例 ID 重查并确认 Name/状态;不得凭历史 IP 判断目标。 + (文档记录 Name=`slark-staging`;2026-10-23 只读核验公网 IP `15.135.112.181`)。公网 IP 自动分配,发布前必须按 + 实例 ID 从 AWS 控制面重查并确认 Name/状态/IP;不得凭历史 IP 或 SSH 可达性判断发布目标。 - `82.157.141.202` 是 ai-proj 预生产宿主机。其 `/opt/slark-staging` cohost 是隔离的 Slark 兼容验收栈, 但不是 Slark 独立预生产;只有任务明确指定 cohost 时才能使用,不得作为普通 Slark staging 的默认目标。 - staging 发布若影响 `packages/daemon`、`packages/runtime`、Server/daemon 公共协议或 Desktop 公共运行链, @@ -75,7 +76,8 @@ git branch -D # 删本地(先切走) ### 3.1 当前权威路径: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 aws ec2 describe-instances --region ap-southeast-2 \ @@ -83,20 +85,93 @@ aws ec2 describe-instances --region ap-southeast-2 \ --query 'Reservations[0].Instances[0].{Name:Tags[?Key==`Name`]|[0].Value,State:State.Name,PublicIp:PublicIpAddress}' \ --output table +# 只使用上一步 AWS 返回且已核对 Name=slark-staging、State=running 的公网 IP。 +export STAGING_IP='' export STAGING_SSH_KEY=~/.ssh/cloud-server-syd.pem -export STAGING_REMOTE=ubuntu@15.135.112.181 -export STAGING_REMOTE_IP=15.135.112.181 -export STAGING_BASE=http://15.135.112.181 +export STAGING_REMOTE="ubuntu@$STAGING_IP" +export STAGING_REMOTE_IP="$STAGING_IP" +export STAGING_BASE="http://$STAGING_IP" +# 使用 Slark 应用内的 project ID,不是 ai-proj 的数字项目/需求/任务 ID。 +export SLARK_RELEASE_PROJECT_ID='' +export SLARK_RELEASE_TASK_ID='REQ-...' +export SLARK_RELEASE_ID='release-staging-<40-sha>-' +# 普通发布还需从既有受信 provider 提供 mirror token;不要打印或写进日志。 -scripts/deploy-staging.sh --migrate-dry-run -scripts/deploy-staging.sh -STAGING_TOKEN=$(cat /tmp/.staging_token) scripts/staging-seed.sh +# 先确认候选 SHA 在 canonical GitHub 上可获取,且包含当前 main 的全部提交。 +bash scripts/release-staging-governed.sh '<40-sha>' scripts/staging-verify-isolation.sh +# 使用上一步发布输出的同一 release receipt;观察窗口未结束时保留原 receipt 重试。 +scripts/complete-staging-verification.sh '' ``` +这是历史 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 发布命令,不能直接照搬。 + +候选若包含 canonical main 尚未收录的 migration,或修改发布控制面,staging admission +只允许在隔离 PDV 中验证,不会切换共享 staging。隔离验证通过后,先按 PR 门禁将改动并入 +canonical main,再用新的 main 精确 SHA 重新准备候选和执行共享 staging 发布;不要把 +`isolated_required` 的成功回执写成共享 staging 已发布。 + +若镜像 token 确实不可读,仓库另有 `deploy-staging.sh --no-mirror --reason '<具体原因>'` +审计路径。仅在已按官方 `staging-candidate.mjs` 生成并核验同一精确 SHA 的 manifest、archive、 +source 和 daemon seed revision 列表,且已满足正常 CI、环境身份和 release admission 门禁时使用; +该路径不读取 Bitwarden、不切换 `staging-latest` 镜像频道。历史先例见 +`docs/reports/REQ-20261012-0006-delivery-status.md`。使用后应明确记录“共享 staging 已发布, +镜像频道未更新”,不能把 no-mirror 写成镜像发布成功。 + 不得把查询到的 Name 非 `slark-staging` 的机器当作目标。四件套细节与环境隔离约束见 `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(仅明确指定时) ai-proj cohost 位于 `ubuntu@82.157.141.202:/opt/slark-staging`。全程使用隔离数据、数据库、密钥和状态目录,