3 changed files with 87 additions and 15 deletions
+1 -1
View File
@@ -365,7 +365,7 @@ install_plugin() {
else
mkdir -p "$dst_dir"
# rsync resolved source (handles nested skills/ structures)
rsync -a --checksum --delete "$src_dir/" "$dst_dir/"
rsync -a --delete "$src_dir/" "$dst_dir/"
state_set "$install_name" "$version" "$effective_install_type" "$source_digest"
ok "$install_name → skill (v$version)"
INSTALL_ACTION=true
+86 -11
View File
@@ -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 <feature-branch> # 删本地(先切走)
### 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='<verified-public-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='<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
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 '<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 发布命令,不能直接照搬。
候选若包含 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`。全程使用隔离数据、数据库、密钥和状态目录,
-3
View File
@@ -42,9 +42,6 @@ description: Installer fixture version two.
---
version two
EOF
# Reproduce rsync's quick-check edge case: changed content with identical size
# and mtime must still replace the recorded, unmodified installation.
touch -r "$TEST_HOME/.agents/skills/example/SKILL.md" "$FIXTURE_REPO/skills-dev/example-plugin/skills/SKILL.md"
HOME="$TEST_HOME" "$FIXTURE_REPO/install-skills.sh" >/dev/null
grep -q 'version two' "$TEST_HOME/.agents/skills/example/SKILL.md"
grep -q '"version": "2.0.0"' "$TEST_HOME/.agents/.ai-proj-helper-installed-skills.json"