如何通过GitHub Actions区分PR的常规提交与分支更新推送?
区分GitHub Action中pull_request synchronize事件的两种触发场景
可以区分这两种场景,核心是通过提交的结构特征或者提交消息格式来判断:
两种场景的核心差异
- 用户手动推送新提交:触发的
synchronize事件对应线性提交链,新提交只有1个父提交,提交消息由用户自定义。 - 通过GitHub界面"Update branch"按钮同步分支:GitHub会自动创建一个合并提交,这个提交有2个父提交(分别对应PR分支原head和base分支的最新head),提交消息格式固定为
Merge branch '<base分支名>' into '<PR分支名>'。
解决方案示例
以下是一个工作流配置,仅在用户手动推送新提交时执行目标步骤:
name: Manual Push Only Action on: pull_request: types: [synchronize] jobs: validate-trigger: runs-on: ubuntu-latest steps: - name: 判断是否为手动推送触发 id: check_trigger run: | # 获取当前提交的父提交数量 PARENT_COUNT=$(gh api repos/${{ github.repository }}/commits/${{ github.sha }} --jq '.parents | length') # 获取提交消息 COMMIT_MSG=$(gh api repos/${{ github.repository }}/commits/${{ github.sha }} --jq '.commit.message') # 双重验证:父提交数量为1,且不是GitHub自动生成的合并消息 if [ "$PARENT_COUNT" -eq 1 ] && [[ ! "$COMMIT_MSG" =~ ^Merge.*into.*$ ]]; then echo "is_manual_push=true" >> $GITHUB_OUTPUT else echo "is_manual_push=false" >> $GITHUB_OUTPUT fi env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 执行仅手动推送时的操作 if: steps.check_trigger.outputs.is_manual_push == 'true' run: | echo "开始执行仅手动推送触发的任务..." # 这里替换为你的实际操作逻辑
注意事项
- GitHub CLI(
gh)默认已预装在GitHub托管的 runners 中,无需额外安装。 GITHUB_TOKEN拥有读取仓库提交信息的权限,工作流默认已包含该密钥。- 如果用户手动创建合并提交并推送,这种极端场景会被误判,但实际开发中这类情况极少发生。
内容的提问来源于stack exchange,提问作者Jallrich
相关产品推荐
相关产品推荐

