Workflow 合并修复说明
问题描述
在 PR 合并后,GitHub Actions 的 Release 创建流程中存在以下问题:
pr-analyzer.yml负责创建/更新 Release 描述create-tag.yml负责打包并上传附件- 问题:
create-tag.yml使用workflow_run触发器监听pr-analyzer.yml的完成,但由于 GitHub Actions 的限制,由pull_request事件触发的 workflow 不会触发workflow_run事件
根本原因
yaml
# 旧配置 - create-tag.yml
on:
workflow_run:
workflows: ["PR 自动分析并更新 Release"]
types: [completed]
branches: [main]当 pr-analyzer.yml 由 pull_request: [closed] 触发时,它完成后不会触发 workflow_run 事件,导致 create-tag.yml 永远不会执行。
解决方案
合并为单一 Workflow
创建新的 release-on-pr-merge.yml,将两个 workflow 合并为一个,通过 needs 关键字控制执行顺序:
yaml
jobs:
analyze-and-update-release:
# Job 1: 分析 PR 并创建/更新 Release 描述
# ...
build-and-upload-assets:
# Job 2: 打包并上传附件
needs: analyze-and-update-release # 等待 Job 1 完成
if: always() && needs.analyze-and-update-release.result == 'success'关键优化点
1. 使用合并后的 main 分支代码
yaml
- name: 检出代码(使用合并后的 main 分支)
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: main # 确保使用的是合并后的 main 分支代码2. Tag 校验机制(防止竞态条件)
yaml
- name: 等待 Release 创建并验证 Tag
run: |
# 等待最多 30 秒,确保 Release 创建完成
MAX_RETRIES=6
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
# 检查 Tag 是否已经生效
if git ls-remote --tags origin | grep -q "refs/tags/${TAG_NAME}$"; then
echo "✅ Tag ${TAG_NAME} 已确认存在"
break
fi
RETRY_COUNT=$((RETRY_COUNT + 1))
echo "⏳ 等待 Tag 生效... ($RETRY_COUNT/$MAX_RETRIES)"
sleep 5
done3. 智能附件检测
yaml
- name: 检查 Release 附件状态
run: |
# 检查是否有附件
ASSETS=$(gh release view "$TAG_NAME" --json assets -q '.assets | length')
if [ "$ASSETS" -eq 0 ]; then
echo "ℹ️ Release 没有附件,将添加附件"
echo "should_upload=true" >> $GITHUB_OUTPUT
else
echo "ℹ️ Release 已有附件,将跳过上传"
echo "should_upload=false" >> $GITHUB_OUTPUT
fi文件变更
新增文件
.github/workflows/release-on-pr-merge.yml- 合并后的 workflow
备份文件
.github/workflows/pr-analyzer.yml.bak- 原 PR 分析 workflow 备份.github/workflows/create-tag.yml.bak- 原附件上传 workflow 备份
删除文件
.github/workflows/pr-analyzer.yml- 已备份.github/workflows/create-tag.yml- 已备份
执行流程
PR 合并到 main
↓
[Job 1: analyze-and-update-release]
├─ 提取 PR 信息
├─ 分析 PR 类型
├─ 读取当前版本
├─ 检查 Release 是否存在
├─ 生成 Release 描述
├─ 创建或更新 Release
├─ 更新 CHANGELOG.md
├─ 发送 PR 评论
└─ 输出: version, release_exists, pr_title, pr_number
↓
[Job 2: build-and-upload-assets] (needs: Job 1)
├─ 检出 main 分支代码
├─ 验证项目结构
├─ 等待并验证 Tag/Release
├─ 检查附件状态
├─ 创建发布资源包 (.tar.gz, .zip)
├─ 上传附件到 Release
├─ 发送 Telegram 通知
└─ 生成发布摘要优势
- 消除竞态条件: 通过
needs确保 Job 1 完成后才执行 Job 2 - 共享上下文: 两个 job 在同一 workflow 中,可以轻松共享变量
- 更好的日志: 所有操作在一个 workflow run 中,便于调试
- 原子性: 要么全部成功,要么全部失败
- 智能重试: Tag 校验机制确保 Release 创建完成后再上传附件
测试验证
下次 PR 合并时,新的 workflow 将自动执行并完成以下任务:
- ✅ 创建/更新 Release 描述
- ✅ 打包项目文件
- ✅ 上传附件(.tar.gz 和 .zip)
- ✅ 发送 PR 评论通知
- ✅ 发送 Telegram 通知
- ✅ 生成 GitHub Actions 摘要
回滚方案
如果需要回滚到旧的分离方案:
bash
cd e:\项目\Sakura-Bot
mv .github\workflows\pr-analyzer.yml.bak .github\workflows\pr-analyzer.yml
mv .github\workflows\create-tag.yml.bak .github\workflows\create-tag.yml
rm .github\workflows\release-on-pr-merge.yml注意事项
- 权限要求: 确保
GITHUB_TOKEN或MY_RELEASE_PAT有contents: write权限 - Tag 同步: Job 2 会等待最多 30 秒以确保 Tag 生效
- 附件去重: 如果 Release 已有附件,Job 2 会跳过上传
- 手动触发: 保留了
workflow_dispatch触发器,可手动执行