GitHub Actions中无法获取subtask/bugfix分支父分支的问题
问题:GitHub Actions中无法获取分支的父分支名称
我配置了一个GitHub Actions工作流,当代码推送到subtask/*或bugfix/*前缀的分支时自动创建PR。这些分支都是从story/*、task/*或production分支拉取创建的。本地执行git命令能正常获取父分支名称,但在GitHub Actions中执行时,PARENT_BRANCH输出为空。
本地可正常运行的命令
# 获取当前分支名称 CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) # 确定父分支 PARENT_BRANCH=$(git show-branch | sed "s/].*//" | grep "*" | grep -v "${CURRENT_BRANCH}" | head -n1 | sed "s/^.*\[//")
GitHub Actions工作流配置
name: Auto-create PR when changes pushed to subtask/* or bugfix/* # 当代码推送到subtask/*或bugfix/*分支时,自动创建PR将其合并到父分支 on: push: branches: - subtask/* - bugfix/* jobs: createPR: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v3 with: repository: {my-repo-name} token: ${{ secrets.GIT_ACCESS_TOKEN }} - name: Determine parent branch id: determine-parent-branch run: | # 获取当前分支名称 CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) # 确定父分支 PARENT_BRANCH=$(git show-branch | sed "s/].*//" | grep "*" | grep -v "${CURRENT_BRANCH}" | head -n1 | sed "s/^.*\[//") echo "PARENT_BRANCH=${PARENT_BRANCH}" - name: Create pull request from ${{ github.ref_name }} to ${{ steps.determine-parent-branch.outputs.PARENT_BRANCH }} uses: repo-sync/pull-request@v2 with: github_token: ${{ secrets.GIT_ACCESS_TOKEN }} pr_label: "automerge" pr_title: "Auto-PR from ${{ github.ref_name }} to ${{ steps.determine-parent-branch.outputs.PARENT_BRANCH }}" destination_branch: ${{ steps.determine-parent-branch.outputs.PARENT_BRANCH }}
问题原因
actions/checkout@v3默认只克隆当前推送的分支,且仅拉取最新的一次提交(浅克隆),本地仓库中没有其他分支的引用信息。而git show-branch需要本地存在父分支的引用才能解析出对应的分支名称,所以在GitHub Actions环境中执行时会返回空值。另外,原步骤中echo "PARENT_BRANCH=${PARENT_BRANCH}"的写法无法将变量设置为步骤输出,后续步骤也无法读取到该值。
解决方案
方案1:调整checkout参数并拉取全部分支
修改checkout步骤,拉取完整仓库历史并同步所有远程分支:
- name: Checkout repository uses: actions/checkout@v3 with: repository: {my-repo-name} token: ${{ secrets.GIT_ACCESS_TOKEN }} fetch-depth: 0 # 拉取完整仓库历史 ref: ${{ github.ref }} - name: Fetch all remote branches run: git fetch origin '+refs/heads/*:refs/remotes/origin/*'
同时修正步骤输出的写法:
- name: Determine parent branch id: determine-parent-branch run: | CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) PARENT_BRANCH=$(git show-branch | sed "s/].*//" | grep "*" | grep -v "${CURRENT_BRANCH}" | head -n1 | sed "s/^.*\[//") echo "PARENT_BRANCH=${PARENT_BRANCH}" >> "$GITHUB_OUTPUT"
方案2:改用更可靠的父分支检测逻辑
不需要依赖本地分支引用,直接通过远程分支判断当前分支的派生来源:
- name: Determine parent branch id: determine-parent-branch run: | CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) # 定义可能的父分支候选列表 PARENT_CANDIDATES=("production" "task/*" "story/*") for candidate in "${PARENT_CANDIDATES[@]}"; do # 匹配远程分支 REMOTE_BRANCHES=$(git ls-remote --heads origin "$candidate") if [[ -n "$REMOTE_BRANCHES" ]]; then for branch in $(echo "$REMOTE_BRANCHES" | awk '{print $2}' | sed 's/refs\/heads\///'); do # 检查当前分支是否从该分支派生 if git merge-base --is-ancestor origin/"$branch" HEAD; then PARENT_BRANCH="$branch" break 2 # 找到后退出循环 fi done fi done echo "PARENT_BRANCH=${PARENT_BRANCH}" >> "$GITHUB_OUTPUT"
内容的提问来源于stack exchange,提问作者Keith Yeoh
相关产品推荐
相关产品推荐

