mcpField
P
post-merge

post-merge

github.com/fellowship-dev云与 DevOps3121 次安装2 周前更新
代码仓库

关于 post-merge

post-merge 是 PR 合并后的自动部署流水线阶段,面向需要按团队配置部署并确认上线状态的项目。它读取合并变更和部署配置,按部署方式执行操作,并派发检查任务。

主要功能

  1. 01读取 PR 信息与变更文件
  2. 02依据团队配置判断部署方式
  3. 03按配置执行手动部署
  4. 04派发部署检查任务并等待上线
  5. 05在 PR 中发布状态并生成报告

适用场景

  1. 01PR 合并后启动部署流程
  2. 02根据团队配置处理手动部署
  3. 03检查 GitHub Actions 部署是否上线
  4. 04为多个部署目标分别派发检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fellowship-dev/dogfooded-skills --skill post-merge

安装后在 Claude Code 中输入/post-merge确认已加载。

详细介绍

post-merge

自主部署流水线的第 1 阶段。在 PR 合并后运行:读取差异,判断部署是自动还是手动,可选执行手动部署,然后派发 deployment-checker 作业,轮询直到部署上线。

适用场景

  • PR 合并到默认分支时,由 event-rules 自动触发
  • 手动触发:/post-merge PR_NUMBER org/repo

调用

/post-merge 42 fellowship-dev/pylot

参数

PR_NUMBER=$1    # PR number
REPO=$2         # org/repo

操作手册

步骤 0:去重检查
PR=$1
REPO=$2

# Check if deployment-checker job already dispatched for this PR
EXISTING=$(ls ${PYLOT_DISPATCH_DIR:-$HOME/.local/share/pylot/missions}/pending/ \
  ${PYLOT_DISPATCH_DIR:-$HOME/.local/share/pylot/missions}/running/ 2>/dev/null \
  | grep "deploy-check-${PR}-" || true)
if [ -n "$EXISTING" ]; then
  echo "[post-merge] outcome=\"already dispatched — deploy-checker job exists\" status=success"
  exit 0
fi
步骤 1:收集 PR 上下文
# Fetch PR metadata
PR_DATA=$(gh pr view $PR --repo $REPO --json number,title,mergedAt,baseRefName,headRefName,files,url,mergeCommit)
PR_TITLE=$(echo "$PR_DATA" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['title'])")
PR_SHA=$(echo "$PR_DATA" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('mergeCommit',{}).get('oid','') or '')" 2>/dev/null || true)
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']))")
BASE_BRANCH=$(echo "$PR_DATA" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['baseRefName'])")

echo "PR: $PR — $PR_TITLE"
echo "SHA: $PR_SHA"
echo "Base: $BASE_BRANCH"
echo "Files changed:"
echo "$CHANGED_FILES"
步骤 2:读取团队部署配置

读取团队的 CLAUDE.md,确定此仓库配置的部署方式。查找 deploy: 部分:

# Example in crew/infra/CLAUDE.md or team CLAUDE.md:
deploy:
  method: auto-pull          # auto-pull | github-actions | manual
  health_url: "http://localhost:1337/_health"
  timeout_minutes: 5
  checker_script: "scripts/deployment-checker-pylot.sh"
  expected_sha_field: "sha"  # JSON field in health response containing deployed sha

部署方式决策树:

方式操作
auto-pull自动部署。跳过步骤 3 和步骤 4(auto-deploy.sh 会处理部署检查)。
github-actions合并后触发部署。等待约 2 分钟,然后执行步骤 4。
manualCTO 现在运行部署命令(步骤 3),然后执行步骤 4。

如果找不到部署配置,发出警告并退出——不要猜测。

步骤 3:手动部署(如果方式为 manual)

仅在 method: manual 时执行。从团队配置中读取部署命令:

# Example: manual deploy for a Fly.io app
cd /path/to/repo && fly deploy --remote-only

# Example: manual ECR push
aws ecr get-login-password | docker login --username AWS --password-stdin $ECR_URI
docker build -t $IMAGE . && docker push $IMAGE

记录执行的命令及其输出。

步骤 4:派发 deployment-checker 作业

如果 method: auto-pull,请跳过此步骤。 auto-pull 仓库会在执行器重启后由 auto-deploy.sh 派发部署检查;在此处派发会造成先有鸡还是先有蛋的死锁(deployment-checker 会阻塞队列,进而阻塞它正在等待的部署)。

对于其他部署方式(github-actions、manual),派发新作业:

if [ "$DEPLOY_METHOD" != "auto-pull" ]; then
  PYLOT_DIR="${PYLOT_DIR:-$HOME/projects/fellowship-dev/pylot}"
  curl -sS -X POST \
    -H "Authorization: Bearer $(grep '^PYLOT_DISPATCH_TOKEN=' $HOME/projects/fellowship-dev/claude-buddy/.env | cut -d= -f2)" \
    -H "Content-Type: application/json" \
    -d "$(python3 -c "import json; print(json.dumps({'agent':'${TEAM}.intern','task':'Check deployment for $REPO#$PR — $PR_TITLE','repo':'$REPO','context':'SHA: $PR_SHA. Health URL: $HEALTH_URL. Timeout: ${TIMEOUT_MINUTES:-5} minutes. Checker script: ${CHECKER_SCRIPT}. Run /deployment-checker $PR $REPO.'}))")" \
    "http://127.0.0.1:3000/dispatch"
else
  echo "[post-merge] Skipping deploy-check dispatch — auto-pull deploys are checked by auto-deploy.sh"
fi
步骤 5:在 PR 上发表评论
gh pr comment $PR --repo $REPO --body "$(cat <<'EOF'
**Post-merge pipeline started** 🚀

| Field | Value |
|-------|-------|
| Deploy method | \`$DEPLOY_METHOD\` |
| Health endpoint | \`$HEALTH_URL\` |
| Timeout | ${TIMEOUT_MINUTES:-5} min |
| Expected SHA | \`${PR_SHA:-unknown}\` |

Deployment checker dispatched. Will apply \`deployed\` or \`deploy-failed\` label when complete.
EOF
)"
步骤 6:编写报告
PYLOT_DIR="${PYLOT_DIR:-$HOME/projects/fellowship-dev/pylot}"
REPORT="$PYLOT_DIR/reports/$(date +%Y-%m-%d)-post-merge-$(echo $REPO | tr '/' '-')-pr${PR}.md"
cat > "$REPORT" <<EOF
# Post-Merge: $REPO PR #$PR — $PR_TITLE

**Date**: $(date +%Y-%m-%d)
**PR**: [$REPO#$PR]($PR_URL)
**SHA**: $PR_SHA
**Deploy method**: $DEPLOY_METHOD
**Deploy-checker job**: dispatched

## Changed Files
$CHANGED_FILES

## Outcome
Deploy-checker dispatched. Awaiting health confirmation.
EOF

团队配置参考

每个团队的 CLAUDE.md 都应包含一个 deploy: 部分。通用示例:

Pylot(auto-pull)
deploy:
  method: auto-pull
  health_url: "http://localhost:1337/_health"
  timeout_minutes: 5
  checker_script: "scripts/deployment-checker-pylot.sh"
  expected_sha_field: "sha"
Lexgo(GitHub Actions → Fly.io)
deploy:
  method: github-actions
  health_url: "https://api.lexgo.cl/_health"
  timeout_minutes: 30
  checker_script: "scripts/deployment-checker-lexgo.sh"
Booster-pack(分支推送 → Fly + Vercel)
deploy:
  method: auto-pull
  health_url: "https://api.booster-pack.dev/health"
  timeout_minutes: 10

注意事项

  • 没有团队配置 = 不采取任何操作。 不要猜测部署方式——缺失配置意味着需要进行配置。
  • SHA 比较尽力而为。 如果健康检查端点未提供 sha 字段,则回退到时间戳比较。
  • 每个 PR 都会触发一次 post-merge。 每个已合并的 PR 都会获得自己的 deployment-checker 作业。
  • 单体仓库: 如果仓库有多个部署目标(例如,后端 + 前端),则为每个目标派发一个检查器。checker_script 会决定要轮询哪个目标。

评论

支持 Markdown