关于 post-deploy
post-deploy 是部署流水线中的后置处理 Skill,根据 PR 改动文件匹配团队配置的规则,并执行相应验证或操作。它支持重建 ECR 镜像、配置重载验证、冒烟测试及自定义命令。
主要功能
- 01按文件匹配团队规则
- 02重建并推送 ECR 镜像
- 03验证配置重载和执行器
- 04运行冒烟测试或自定义命令
- 05向 PR 评论并生成报告
适用场景
- 01部署确认后执行针对性检查
- 02代码变更后重建容器镜像
- 03检查配置更新是否已加载
- 04为 PR 汇总后置操作结果
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ fellowship-dev/ dogfooded-skills --skill post-deploy安装后在 Claude Code 中输入/post-deploy确认已加载。
详细介绍
部署后
自治部署流水线的第 3 阶段。由 deployed 标签触发。读取 PR 中已更改的文件,将其与已配置的模式匹配,然后执行定向操作:ECR 镜像重建、配置重新加载验证、冒烟测试或自定义脚本。
适用场景
- 通过 event-rules 中的
deployed标签触发(deployment-checker 确认线上部署后) - 手动:
/post-deploy PR_NUMBER org/repo
调用方式
/post-deploy 42 fellowship-dev/pylot
操作手册
步骤 0:去重检查
PR=$1
REPO=$2
# Check if post-deploy already ran (look for a post-deploy comment)
EXISTING=$(gh pr view $PR --repo $REPO --json comments \
--jq '.comments[].body' | grep "Post-deploy actions" || true)
if [ -n "$EXISTING" ]; then
echo "[post-deploy] outcome=\"already complete — post-deploy comment found\" status=success"
exit 0
fi
步骤 1:读取 PR 上下文
PR_DATA=$(gh pr view $PR --repo $REPO --json number,title,url,files,mergeCommit,baseRefName)
PR_TITLE=$(echo "$PR_DATA" | python3 -c "import json,sys; print(json.load(sys.stdin)['title'])")
PR_URL=$(echo "$PR_DATA" | python3 -c "import json,sys; print(json.load(sys.stdin)['url'])")
CHANGED_FILES=$(echo "$PR_DATA" | python3 -c "
import json,sys
d = json.load(sys.stdin)
print('\n'.join(f['path'] for f in d['files']))
")
echo "PR: $PR — $PR_TITLE"
echo "Changed files:"
echo "$CHANGED_FILES"
步骤 2:读取团队的部署后配置
读取团队的 CLAUDE.md 中的 post_deploy: 规则。每条规则将文件 glob 模式映射到一个操作:
# Example in team CLAUDE.md:
post_deploy:
- match: "Dockerfile*"
action: ecr-rebuild
description: "Rebuild and push ECR image"
- match: "docker-entrypoint.sh"
action: ecr-rebuild
- match: "crew.yml"
action: config-reload-verify
description: "Verify gateway reloaded updated config"
- match: "scripts/*.sh"
action: executor-verify
description: "Spot-check executor behavior"
- match: "event-rules.yml"
action: config-reload-verify
- match: "**"
action: smoke-test
optional: true
description: "Optional smoke test for any PR"
操作类型:
| 操作 | 描述 |
|---|---|
ecr-rebuild | 重建 Docker 镜像并推送到 ECR |
config-reload-verify | 验证进程/网关是否已重新加载更新后的配置 |
executor-verify | 抽查执行器或脚本的行为 |
smoke-test | 运行团队定义的冒烟测试 |
custom | 将 command 字段作为 shell 命令运行 |
步骤 3:将文件与操作匹配
# Pseudocode — implement in bash with Python for glob matching
import fnmatch
changed = CHANGED_FILES.splitlines()
triggered_actions = []
for rule in post_deploy_rules:
pattern = rule['match']
matching = [f for f in changed if fnmatch.fnmatch(f, pattern)]
if matching:
triggered_actions.append({
'action': rule['action'],
'description': rule.get('description', rule['action']),
'matched_files': matching,
'optional': rule.get('optional', False)
})
步骤 4:执行操作
运行每项触发的操作。记录每项操作的结果。
操作:ecr-rebuild
# Rebuild and push ECR image
PYLOT_DIR="${PYLOT_DIR:-$HOME/projects/fellowship-dev/pylot}"
ECR_URI="${ECR_URI:-$(grep 'fargate_ecr_uri' $PYLOT_DIR/crew.yml | awk '{print $2}')}"
cd "$PYLOT_DIR"
bash scripts/build-worker-image.sh 2>&1
ECR_EXIT=$?
[ $ECR_EXIT -eq 0 ] && echo "ecr-rebuild: success" || echo "ecr-rebuild: failed exit=$ECR_EXIT"
操作:config-reload-verify
# Verify the executor/gateway has reloaded the updated config
# For Pylot: check that crew.yml timestamp matches what executor loaded
PYLOT_DIR="${PYLOT_DIR:-$HOME/projects/fellowship-dev/pylot}"
# Check if executor is running and has loaded recent config
CREW_MTIME=$(stat -c %Y "$PYLOT_DIR/crew.yml" 2>/dev/null || stat -f %m "$PYLOT_DIR/crew.yml" 2>/dev/null)
EXECUTOR_PID=$(pgrep -f "executor.sh" || true)
if [ -n "$EXECUTOR_PID" ]; then
echo "config-reload-verify: executor running (pid=$EXECUTOR_PID). crew.yml mtime=$CREW_MTIME."
echo "config-reload-verify: success — executor will pick up config on next poll cycle"
else
echo "config-reload-verify: WARNING — executor not running. Config will load on restart."
fi
操作:executor-verify
# Spot-check executor behavior — run a quick test
PYLOT_DIR="${PYLOT_DIR:-$HOME/projects/fellowship-dev/pylot}"
# Syntax-check the modified scripts
for script in $MATCHED_SCRIPTS; do
bash -n "$PYLOT_DIR/$script" && echo "executor-verify: $script syntax OK" || echo "executor-verify: $script SYNTAX ERROR"
done
操作:smoke-test
运行团队配置的冒烟测试。默认情况下为可选操作。
# Team-specific smoke test — read from CLAUDE.md smoke_test.command
# Example for Pylot: run a dry-run event dispatch
PYLOT_DIR="${PYLOT_DIR:-$HOME/projects/fellowship-dev/pylot}"
bash "$PYLOT_DIR/event-router.sh" --dry-run 2>&1 | head -20
echo "smoke-test: event-router dry-run complete"
步骤 5:发布总结评论
# Build table rows before heredoc (<<'EOF' prevents expansion — pre-build instead)
ACTION_TABLE=""
for action_entry in $TRIGGERED_ACTION_ENTRIES; do
ACTION_NAME=$(echo "$action_entry" | cut -d: -f1)
ACTION_FILES=$(echo "$action_entry" | cut -d: -f2)
ACTION_RESULT=$(echo "$action_entry" | cut -d: -f3)
ACTION_TABLE="${ACTION_TABLE}| ${ACTION_NAME} | ${ACTION_FILES} | ${ACTION_RESULT} |\n"
done
[ -z "$ACTION_TABLE" ] && ACTION_TABLE="_No file-match rules triggered for this PR's changed files._\n"
gh pr comment $PR --repo $REPO --body "$(printf '%s' "## Post-deploy actions
| Action | Matched Files | Result |
|--------|--------------|--------|
$(printf '%b' "$ACTION_TABLE")
**Pipeline complete.** This PR is live and verified.")"
步骤 6:撰写报告
PYLOT_DIR="${PYLOT_DIR:-$HOME/projects/fellowship-dev/pylot}"
REPORT="$PYLOT_DIR/reports/$(date +%Y-%m-%d)-post-deploy-$(echo $REPO | tr '/' '-')-pr${PR}.md"
cat > "$REPORT" <<EOF
# Post-Deploy: $REPO PR #$PR — $PR_TITLE
**Date**: $(date +%Y-%m-%d)
**PR**: [$REPO#$PR]($PR_URL)
## Changed Files
$CHANGED_FILES
## Actions Triggered
$TRIGGERED_ACTIONS_SUMMARY
## Results
$ACTIONS_RESULTS
EOF
默认文件匹配规则(Pylot)
| 模式 | 操作 | 适用情况 |
|---|---|---|
Dockerfile* | ecr-rebuild | Docker 镜像已更改 |
docker-entrypoint.sh | ecr-rebuild | Entrypoint 脚本已更改 |
crew.yml | config-reload-verify | Crew 配置已更改 |
event-rules.yml | config-reload-verify | 事件路由已更改 |
scripts/*.sh | executor-verify | Shell 脚本已更改 |
dispatch.sh | executor-verify | 分发逻辑已更改 |
executor.sh | executor-verify | 执行器逻辑已更改 |
注意事项
- 没有匹配的规则 = 不执行任何操作。 仅修改 Markdown 文件的 PR 不会触发任何操作。这是正确行为。
- 可选操作(smoke-test)会运行,但不会影响总结结论。
- ecr-rebuild 失败应作为评论说明,但不会重新应用
deploy-failed标签——部署本身已通过验证。应改为创建后续跟进问题。 - 团队配置具有权威性。 通用技能 + 团队 CLAUDE.md = 无需修改技能即可实现完整配置。
- Monorepo: 如果团队有多个部署目标,应按每个目标的规则匹配文件。
评论
支持 Markdown