1. 概述

GitHub Actions 是一个强大的自动化平台,广泛用于持续集成与持续交付(CI/CD)流程。在与 GitHub 仓库协作时,一个常见的需求是通过自动化手段创建 Pull Request(PR),例如在自动更新时间戳、同步生成文件或批量修改多个分支时。

在本教程中,我们将探讨通过 GitHub Actions 创建 Pull Request 的多种方式,包括使用 GitHub CLI、REST API 以及 peter-evans/create-pull-request 这个社区广泛使用的 Action。


2. 准备工作

在 GitHub Actions 工作流中创建 Pull Request 前,我们需要确保 Git 正确配置,并通过 Token 进行认证。

我们先创建一个复合 Action(composite action),用于配置 Git 用户信息并设置认证:

# .github/actions/setup-repo/action.yml
name: 'Setup Git Repository'
description: 'Configure Git user and authentication for commits'
inputs:
  token:
    description: 'GitHub token'
    required: true
runs:
  using: 'composite'
  steps:
    - name: Configure Git user
      run: |
        git config --global user.name "github-actions[bot]"
        git config --global user.email "github-actions[bot]@users.noreply.github.com"
      shell: bash

    - name: Authenticate using token
      run: |
        git remote set-url origin https://x-access-token:${{ inputs.token }}@github.com/${{ github.repository }}
      shell: bash

接下来,我们定义另一个复合 Action,用于更新文件并推送到新分支:

# .github/actions/update-and-push/action.yml
name: 'Update File and Push Branch'
description: 'Creates a new branch, modifies a file, commits, and pushes'
inputs:
  update_only:
    required: false
    default: false

outputs:
  branch:
    description: 'Branch name'
    value: ${{ steps.push.outputs.branch }}

runs:
  using: 'composite'
  steps:
    - name: Update file
      run: echo "Updated at $(date -u --rfc-3339=ns)" > gh-update.txt
      shell: bash

    - name: Commit and push
      id: push
      run: |
        branch="gh/update-$(date +%s)"
        if [ "${{ inputs.update_only }}" = "false" ]; then
          git checkout -b "$branch"
          git add gh-update.txt
          git commit -m "chore: update file"
          echo "Pushing branch: $branch"
          git push origin "$branch"
        else
          echo "Skipping push as update_only is true"
        fi

        echo "branch=$branch" >> "$GITHUB_OUTPUT"
      shell: bash

✅ 这个 Action 会创建一个带时间戳的新分支,并更新 gh-update.txt 文件内容。update_only 参数用于控制是否跳过提交和推送。

最后,我们需要创建一个具有 repo 权限的 Personal Access Token(PAT),并将其作为仓库的 Secret 存储为 GH_TOKEN


3. 使用 GitHub CLI 创建 PR

GitHub CLI 提供了一个便捷的命令行方式与 GitHub 仓库交互。我们可以在工作流中使用 gh pr create 命令创建 Pull Request。

以下是完整的工作流配置:

# .github/workflows/create-pr-gh-cli.yml
name: "Create Pull Request via GitHub CLI"

on:
  workflow_dispatch:

jobs:
  create-pr:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false

      - uses: ./.github/actions/setup-repo
        with:
          token: ${{ secrets.GH_TOKEN }}

      - uses: ./.github/actions/update-and-push

      - name: Open pull request using gh CLI
        run: |
          gh pr create \
            --title "chore: update via gh cli" \
            --body "This PR was created using the GitHub CLI." \
            --base main \
            --head $(git rev-parse --abbrev-ref HEAD)
        env:
          GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}

✅ 该工作流会自动创建 PR,并使用当前分支作为 head

执行结果

运行后,你将在仓库中看到新创建的 PR:

Create PR using GitHub CLI


4. 使用 GitHub REST API 创建 PR

如果你不想依赖 CLI 工具,也可以直接调用 GitHub 的 REST API 来创建 PR。

以下是使用 REST API 的完整工作流:

# .github/workflows/create-pr-rest.yml
name: "Create Pull Request via REST API"

on:
  workflow_dispatch:

jobs:
  create-pr:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false

      - uses: ./.github/actions/setup-repo
        with:
          token: ${{ secrets.GH_TOKEN }}

      - uses: ./.github/actions/update-and-push

      - name: Open pull request via REST API
        run: |
          curl -X POST \
            -H "Authorization: token ${{ secrets.GH_TOKEN }}" \
            -H "Accept: application/vnd.github+json" \
            https://api.github.com/repos/${{ github.repository }}/pulls \
            -d "$(jq -n \
              --arg title 'chore: daily timestamp update' \
              --arg head "$(git rev-parse --abbrev-ref HEAD)" \
              --arg base 'main' \
              --arg body 'This PR updates the timestamp file automatically via GitHub Actions.' \
              '{title: $title, head: $head, base: $base, body: $body}')"

✅ 我们使用了 jq 工具构造 JSON 请求体,调用 /pulls 接口创建 PR。

执行结果

运行后,你将在仓库中看到如下 PR:

Create PR using REST API


5. 使用 peter-evans/create-pull-request Action

如果你希望使用一个开箱即用的解决方案,推荐使用社区维护的 peter-evans/create-pull-request Action。它封装了完整的 PR 创建逻辑,包括提交更改和创建 PR。

以下是使用该 Action 的完整工作流:

# .github/workflows/create-pr-peter-evans.yml
name: "Create Pull Request via peter-evans Action"

on:
  workflow_dispatch:

jobs:
  create-pr:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false

      - uses: ./.github/actions/setup-repo
        with:
          token: ${{ secrets.GH_TOKEN }}

      - uses: ./.github/actions/update-and-push
        id: update
        with:
          update_only: true

      - name: Open pull request using peter-evans action
        uses: peter-evans/create-pull-request@v5
        with:
          branch: ${{ steps.update.outputs.branch }}
          base: main
          commit-message: "chore: update via create-pull-request action"
          title: "chore: update via create-pull-request action"
          body: "This PR was created using the peter-evans/create-pull-request action."
          token: ${{ secrets.GH_TOKEN }}

✅ 该 Action 会自动将未提交的更改提交到指定分支并创建 PR。

执行结果

运行后,你将在仓库中看到如下 PR:

Create PR using composite action


6. 总结

本教程中,我们探讨了三种在 GitHub Actions 中创建 Pull Request 的方式:

方法 特点 适用场景
GitHub CLI 简洁易用,适合熟悉命令行的开发者 快速原型或脚本化流程
REST API 灵活可控,适合已有封装逻辑的项目 自定义 CI/CD 流程
peter-evans/create-pull-request 开箱即用,社区维护 生产级自动化流程

你可以根据项目需求和团队习惯选择最适合的方式。

✅ 踩坑提醒:记得为 Token 添加 repo 权限,否则会遇到权限拒绝错误。另外,创建 PR 的分支必须存在于远程仓库中,否则会失败。


原始标题:Create Pull Request With GitHub Actions