The automation of software development workflows represents a critical component of modern DevOps practices, shifting manual repository maintenance tasks toward declarative, code-driven processes. Within the GitHub Actions ecosystem, the ability to generate, modify, and manage pull requests programmatically allows teams to enforce standards, automate reporting, and streamline the integration of changes without direct human intervention. The peter-evans/create-pull-request action serves as a specialized tool for this purpose, enabling workflows to detect changes made within the Actions workspace—whether new files, modified tracked files, or unpushed commits—and consolidate them into a pull request targeting a base branch. This capability is particularly valuable for tasks such as generating daily reports, updating documentation, or synchronizing configuration files, where the changes are transient, automated, and require formal review or tracking within the repository’s history.
Core Functionality and Workspace Persistence
The fundamental mechanism underlying the create-pull-request action relies on the persistence of the Actions workspace across different steps within a single workflow job. When a workflow initiates, the repository is typically checked out into the runner’s file system. Any subsequent steps that modify this file system—creating new files, editing existing ones, or committing changes locally—leave their mark in the workspace. The action is designed to inspect this workspace state and reconcile it with the repository’s remote state. It identifies untracked files, tracked files that have been modified, and commits that were made during the workflow execution but have not yet been pushed to the remote repository.
Upon detecting these changes, the action performs a sequence of operations to formalize them. It commits the detected changes to a new branch, or if a branch already exists with the same name, it updates that existing branch. Following the commit, the action creates a pull request to merge this feature or patch branch into the base branch, which is defined as the branch that was originally checked out during the workflow. If a pull request already exists for that branch, the action updates it rather than creating a duplicate. This ensures that the repository’s pull request list remains clean and that the most recent state of the automated changes is always represented.
To utilize this action, specific permissions must be configured. GitHub Actions requires explicit authorization to create pull requests, a security measure designed to prevent unauthorized modifications to repository history. This permission is managed within the repository settings under Actions, General, and Workflow permissions. For repositories within an organization, administrators control these settings at the organization level, allowing for centralized governance of automated actions. Without these permissions enabled, the action will fail to push branches or create pull requests, highlighting the importance of proper administrative configuration before deployment.
Configuration and Input Parameters
The create-pull-request action is highly configurable, with all inputs being optional and possessing sensible defaults. This design allows users to start with minimal configuration and expand upon it as their automation needs become more complex. The action accepts a wide range of parameters that control the metadata, targeting, and behavior of the generated pull request.
The title and body inputs define the primary content of the pull request. By default, the title is set to "Changes by create-pull-request action" and the body to "Automated changes by create-pull-request GitHub action". Users can override these with custom messages, such as "[Example] Update report" for the title and a detailed markdown body for the description. The body-path input offers an alternative method for defining the body by specifying the path to a file containing the pull request description, which takes precedence over the body input. This is useful when the description is generated dynamically by a previous step in the workflow.
Branch management is controlled by several inputs. The branch input specifies the name of the pull request branch, defaulting to create-pull-request/patch. For scenarios requiring unique branch names to avoid conflicts, the branch-suffix input allows for the appending of a random string, timestamp, or short commit hash. The base input defines the target branch for the pull request, defaulting to the branch checked out in the workflow. The delete-branch input, when set to true, ensures that the branch is deleted if it does not have an active pull request associated with it, helping to keep the repository free of stale branches.
Authorship and commit signing are critical for maintaining the integrity and auditability of automated changes. The committer input defaults to the github-actions[bot] user, with the email 41898282+github-actions[bot]@users.noreply.github.com. The author input defaults to the user who triggered the workflow run, utilizing the github.actor and github.actor_id contexts. The signoff input can be enabled to add a "Signed-off-by" line to the commit log, complying with the Developer Certificate of Origin (DCO) requirement for many open-source projects. The sign-commits input allows for cryptographic signing of commits, using the github-actions[bot] identity when using the default GITHUB_TOKEN, or a custom bot identity when using GitHub App tokens.
Workflow Context and Dynamic Data Injection
The power of the create-pull-request action is significantly enhanced by its ability to leverage GitHub Actions contexts to inject dynamic data into the workflow. Contexts provide access to information about the current workflow run, the event that triggered it, and the environment in which it is executing. By integrating these contexts into the action’s inputs, users can create highly adaptive and informative pull requests.
The github.actor context provides the username of the user who triggered the initial workflow run. This is distinct from github.triggering_actor, which may differ in the case of a re-run. The github.actor_id provides the numerical account ID associated with that user. These values are frequently used to set the author field of the pull request, ensuring that the human behind the automation is credited. For example, the author can be set to ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>.
The github.event context exposes the full event webhook payload that triggered the workflow. This object contains detailed information about the trigger, such as the commit message for a push event or the changes made in a pull request. Specific properties can be accessed using dot notation, such as github.event.head_commit.message. The github.event_name context provides the name of the event, such as push or pull_request, allowing the workflow to adapt its behavior based on the trigger. The github.ref context provides the fully-formed ref of the branch or tag that triggered the workflow, such as refs/heads/feature-branch-1 or refs/tags/v1.0.0. The github.ref_name provides the short name, such as feature-branch-1.
Other useful contexts include github.base_ref and github.head_ref, which are available for pull_request and pull_request_target events and indicate the target and source branches, respectively. The github.api_url and github.graphql_url contexts provide the endpoints for the REST and GraphQL APIs, useful for steps that need to interact with GitHub’s API directly. The github.job context provides the ID of the current job, while github.path and github.env provide paths to files that set system PATH and environment variables, respectively.
Advanced Use Cases and Permissions
Beyond basic file updates, the create-pull-request action supports advanced scenarios such as pushing changes to a fork. The push-to-fork input allows users to specify a fork of the parent repository (e.g., owner/repo-fork) to which the pull request branch will be pushed. This is useful when the workflow runs in a context where pushing directly to the parent repository is not permitted or desired. The pull request is then created to merge the fork’s branch into the parent’s base branch.
The action also supports the assignment of metadata to the pull request. The labels input accepts a comma or newline-separated list of labels, such as report or automated pr. The assignees and reviewers inputs allow for the assignment of specific users, such as peter-evans, to the pull request. The team-reviewers input extends this capability to GitHub teams, such as developers or qa-team, though it requires a repository-scoped Personal Access Token (PAT) or equivalent GitHub App permissions. The milestone input allows the pull request to be associated with a specific project milestone by its number. The draft input can create a draft pull request, with options for true (only on create), always-true (on create and update), or false. The maintainer-can-modify input indicates whether maintainers can modify the pull request, such as by editing the description or merging it directly.
It is important to note that the create-pull-request action is a third-party tool, not certified by GitHub. It is governed by separate terms of service, privacy policy, and support documentation. Users should be aware of this distinction and ensure that they understand the implications of using third-party actions in their workflows. For those requiring automatic merging of pull requests after they are created, the enable-pull-request-automerge action can be used in conjunction with create-pull-request.
Example Workflow Configuration
A typical implementation of the create-pull-request action involves a sequence of steps that checkout the repository, make changes, and then create the pull request. The following configuration demonstrates a comprehensive use of the action’s inputs, leveraging GitHub Actions contexts for dynamic data.
yaml
jobs:
createPullRequest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Make changes to pull request
run: date +%s > report.txt
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.PAT }}
commit-message: Update report
committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
author: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>
signoff: false
branch: example-patches
delete-branch: true
title: '[Example] Update report'
body: |
Update report
- Updated with *today's* date
- Auto-generated by [create-pull-request][1]
[1]: https://github.com/peter-evans/create-pull-request
labels: |
report
automated pr
assignees: peter-evans
reviewers: peter-evans
team-reviewers: |
developers
qa-team
milestone: 1
draft: false
In this example, the workflow runs on an ubuntu-latest runner. The first step checks out the repository using actions/checkout@v6. The second step creates a new file report.txt containing the current Unix timestamp. The third step invokes the create-pull-request action, pinning to version v8. It uses a Personal Access Token (secrets.PAT) for authentication, which is necessary for many advanced features. The commit message is set to "Update report", and the author is dynamically set to the user who triggered the workflow. The branch is named example-patches, and the pull request title is "[Example] Update report". The body includes a formatted list of changes. Labels, assignees, reviewers, and team reviewers are specified to ensure proper tracking and review. The delete-branch option is set to true to clean up the branch after the pull request is merged or closed.
Conclusion
The peter-evans/create-pull-request action provides a robust and flexible mechanism for automating pull request creation within GitHub Actions workflows. By leveraging the persistence of the Actions workspace and the rich context data provided by GitHub, it enables developers to automate a wide range of repository maintenance tasks. From simple file updates to complex branching strategies involving forks and team reviews, the action offers granular control over every aspect of the pull request lifecycle. Proper configuration of permissions, particularly the workflow permissions for creating pull requests, is essential for its successful operation. As automation continues to play an increasingly central role in software development, tools like this become indispensable for maintaining efficiency, consistency, and security in repository management.